Annotation of Amaya/amaya/styleparser.c, revision 1.308

1.1       cvs         1: /*
                      2:  *
1.249     vatton      3:  *  (c) COPYRIGHT INRIA and W3C, 1996-2004
1.1       cvs         4:  *  Please first read the full copyright statement in file COPYRIGHT.
                      5:  *
                      6:  */
1.164     quint       7: 
1.1       cvs         8: /*
1.164     quint       9:  * Everything directly related to the CSS syntax should now hopefully
1.1       cvs        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.100     vatton     21: #include "SVG.h"
1.107     cvs        22: #include "XML.h"
1.141     cvs        23: #include "document.h"
1.1       cvs        24: 
1.302     quint      25: typedef struct _CSSImageCallbackBlock
1.1       cvs        26: {
1.207     vatton     27:   Element                el;
                     28:   PSchema                tsch;
                     29:   CSSInfoPtr             css;
                     30:   PresentationContext    ctxt;
1.302     quint      31:   unsigned int           ruleType;
1.1       cvs        32: }
1.302     quint      33: CSSImageCallbackBlock, *CSSImageCallbackPtr;
1.1       cvs        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: 
1.86      cvs        68: static char         *DocURL = NULL; /* The parsed CSS file */
                     69: static int           LineNumber = -1; /* The line where the error occurs */
1.93      vatton     70: static int           NewLineSkipped = 0;
1.116     vatton     71: static ThotBool      DoApply = TRUE;
1.1       cvs        72: 
1.308   ! vatton     73: 
1.1       cvs        74: /*----------------------------------------------------------------------
                     75:    SkipWord:                                                  
                     76:   ----------------------------------------------------------------------*/
1.79      cvs        77: static char *SkipWord (char *ptr)
1.1       cvs        78: {
1.168     vatton     79:   while (isalnum((int)*ptr) || *ptr == '-' || *ptr == '#' || *ptr == '%')
                     80:     ptr++;
1.1       cvs        81:   return (ptr);
                     82: }
                     83: 
                     84: /*----------------------------------------------------------------------
1.13      cvs        85:    SkipBlanksAndComments:                                                  
                     86:   ----------------------------------------------------------------------*/
1.82      cvs        87: char *SkipBlanksAndComments (char *ptr)
1.13      cvs        88: {
1.93      vatton     89:   /* skip spaces */
1.155     cheyroul   90:   while (*ptr == SPACE ||
                     91:         *ptr == BSPACE ||
                     92:         *ptr == EOL ||
                     93:         *ptr == TAB ||
                     94:         *ptr == __CR__)
1.93      vatton     95:     {
                     96:       if (*ptr == EOL)
                     97:        /* increment the number of newline skipped */
                     98:        NewLineSkipped++;
                     99:       ptr++;
                    100:     }
1.155     cheyroul  101:   while (ptr[0] == '/' &&
                    102:         ptr[1] == '*')
1.13      cvs       103:     {
                    104:       /* look for the end of the comment */
                    105:       ptr = &ptr[2];
                    106:       while (ptr[0] != EOS && (ptr[0] != '*' || ptr[1] != '/'))
                    107:        ptr++;
                    108:       if (ptr[0] != EOS)
                    109:        ptr = &ptr[2];
1.93      vatton    110:       /* skip spaces */
                    111:       while (*ptr == SPACE || *ptr == BSPACE || *ptr == EOL ||
                    112:             *ptr == TAB || *ptr == __CR__)
                    113:        {
                    114:          if (*ptr == EOL)
                    115:            /* increment the number of newline skipped */
                    116:            NewLineSkipped++;
                    117:          ptr++;
                    118:        }
1.13      cvs       119:     }
                    120:   return (ptr);
                    121: }
                    122: 
1.49      cvs       123: /*----------------------------------------------------------------------
1.161     quint     124:    SkipQuotedString
1.1       cvs       125:   ----------------------------------------------------------------------*/
1.79      cvs       126: static char *SkipQuotedString (char *ptr, char quote)
1.1       cvs       127: {
1.14      cvs       128:   ThotBool     stop;
1.1       cvs       129: 
                    130:   stop = FALSE;
                    131:   while (!stop)
                    132:     {
                    133:     if (*ptr == quote)
                    134:        {
                    135:        ptr++;
                    136:        stop = TRUE;
                    137:        }
1.82      cvs       138:     else if (*ptr == EOS)
1.1       cvs       139:        stop = TRUE;
1.82      cvs       140:     else if (*ptr == '\\')
1.1       cvs       141:        /* escape character */
                    142:        {
                    143:        ptr++;
1.82      cvs       144:        if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
                    145:           (*ptr >= 'a' && *ptr <= 'f'))
1.1       cvs       146:          {
                    147:          ptr++;
1.82      cvs       148:           if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
                    149:              (*ptr >= 'a' && *ptr <= 'f'))
1.1       cvs       150:             ptr++;
                    151:          }
                    152:        else
                    153:          ptr++;
                    154:        }
                    155:     else
                    156:        ptr++;
                    157:     }
                    158:   return (ptr);
                    159: }
                    160: 
                    161: /*----------------------------------------------------------------------
1.168     vatton    162:    CSSPrintError
1.86      cvs       163:    print the error message msg on stderr.
                    164:    When the line is 0 ask to expat the current line number
                    165:   ----------------------------------------------------------------------*/
1.168     vatton    166: static void CSSPrintError (char *msg, char *value)
1.86      cvs       167: {
                    168:   if (!TtaIsPrinting () && ParsedDoc > 0)
                    169:     {
                    170:       if (!ErrFile)
                    171:        {
1.90      cvs       172:          if (OpenParsingErrors (ParsedDoc) == FALSE)
1.86      cvs       173:            return;
                    174:        }
                    175: 
1.308   ! vatton    176:       /* check if a CSS error file shoulb be updated too */
        !           177:       if (ParsedCSS > 0 && !CSSErrFile)
        !           178:        OpenParsingErrors (ParsedCSS);
        !           179: 
1.133     vatton    180:       if (DocURL)
1.86      cvs       181:        {
1.241     vatton    182:          fprintf (ErrFile, "\n*** Errors/warnings in %s\n", DocURL);
1.86      cvs       183:          /* set to NULL as long as the CSS file doesn't change */
                    184:          DocURL = NULL;
                    185:        }
1.89      cvs       186:       CSSErrorsFound = TRUE;
1.86      cvs       187:       if (LineNumber < 0)
1.205     quint     188:        fprintf (ErrFile, "  In style attribute, %s \"%s\"\n", msg, value);
1.86      cvs       189:       else
1.308   ! vatton    190:        {
        !           191:          fprintf (ErrFile, "@  line %d: %s \"%s\"\n",
        !           192:                   LineNumber+NewLineSkipped, msg, value);
        !           193:          if (CSSErrFile)
        !           194:            fprintf (CSSErrFile, "@  line %d: %s \"%s\"\n",
        !           195:                     LineNumber+NewLineSkipped, msg, value);
        !           196:        }
1.86      cvs       197:     }
                    198: }
                    199: 
1.168     vatton    200: /*----------------------------------------------------------------------
                    201:    CSSParseError
                    202:    print the error message msg on stderr.
1.230     quint     203:    When the line is 0 ask expat about the current line number
1.168     vatton    204:   ----------------------------------------------------------------------*/
                    205: static void CSSParseError (char *msg, char *value, char *endvalue)
                    206: {
1.230     quint     207:   char        c = EOS;
1.168     vatton    208: 
                    209:   if (endvalue)
                    210:     {
                    211:       /* close the string here */
                    212:       c = *endvalue;
                    213:       *endvalue = EOS;
                    214:     }
                    215:   CSSPrintError (msg, value);
                    216:   if (endvalue)
                    217:     *endvalue = c;
                    218: }
                    219: 
1.288     vatton    220: /*----------------------------------------------------------------------
                    221:    CSSCheckEndValue
                    222:    print an error message if another character is found
                    223:   ----------------------------------------------------------------------*/
                    224: static char *CSSCheckEndValue (char *cssRule, char *endvalue, char *msg)
                    225: {
                    226:   char        c = EOS;
                    227:   if (*endvalue != EOS && *endvalue != SPACE && *endvalue != '/' &&
1.301     vatton    228:       *endvalue != ';' && *endvalue != '}' && *endvalue != EOL && *endvalue != TAB &&
1.288     vatton    229:       *endvalue !=  __CR__)
                    230:     {
                    231:       while (*endvalue != EOS && *endvalue != SPACE && *endvalue != '/' &&
1.301     vatton    232:             *endvalue != ';' && *endvalue != '}' && *endvalue != EOL && *endvalue != TAB &&
1.288     vatton    233:             *endvalue !=  __CR__)
                    234:        endvalue++;
                    235:       /* close the string here */
                    236:       c = *endvalue;
                    237:       *endvalue = EOS;
                    238:       CSSPrintError (msg, cssRule);
                    239:       *endvalue = c;
                    240:     }
                    241:   return endvalue;
                    242: }
                    243: 
1.89      cvs       244: 
1.86      cvs       245: /*----------------------------------------------------------------------
1.168     vatton    246:    SkipProperty skips a property and display and error message
1.86      cvs       247:   ----------------------------------------------------------------------*/
1.234     vatton    248: static char *SkipProperty (char *ptr, ThotBool reportError)
1.86      cvs       249: {
                    250:   char       *deb;
1.291     cvs       251: #ifdef IV
1.86      cvs       252:   char        c;
1.291     cvs       253: #endif
1.86      cvs       254: 
                    255:   deb = ptr;
1.301     vatton    256:   while (*ptr != EOS && *ptr != ';' && *ptr != '}' && *ptr != '}')
1.133     vatton    257:     {
1.194     vatton    258:       if (*ptr == '"' && (ptr == deb || ptr[-1] != '\\'))
1.133     vatton    259:        {
                    260:          /* skip to the end of the string "..." */
                    261:          ptr++;
1.194     vatton    262:          while (*ptr != EOS &&
                    263:                 (*ptr != '"' || (*ptr == '"' && ptr[-1] == '\\')))
1.133     vatton    264:            ptr++;
                    265:        }
                    266:       ptr++;
                    267:     }
1.288     vatton    268: #ifdef IV
1.95      cvs       269:   /* print the skipped property */
1.86      cvs       270:   c = *ptr;
                    271:   *ptr = EOS;
1.234     vatton    272:   if (reportError && *deb != EOS &&
1.259     vatton    273:       strncasecmp (deb, "border-collapse", 15) &&
1.234     vatton    274:       strncasecmp (deb, "border-spacing", 14) &&
                    275:       strncasecmp (deb, "caption-side", 12) &&
                    276:       strncasecmp (deb, "clip", 4) &&
                    277:       strncasecmp (deb, "counter-increment", 16) &&
                    278:       strncasecmp (deb, "counter-reset", 13) &&
                    279:       strncasecmp (deb, "cursor", 6) &&
                    280:       strncasecmp (deb, "empty-cells", 11) &&
1.259     vatton    281:       strncasecmp (deb, "font-strech", 11) &&
1.234     vatton    282:       strncasecmp (deb, "letter-spacing", 14) &&
1.242     vatton    283:       strncasecmp (deb, "marker-offset", 12) &&
1.234     vatton    284:       strncasecmp (deb, "max-height", 10) &&
                    285:       strncasecmp (deb, "max-width", 9) &&
                    286:       strncasecmp (deb, "min-height", 10) &&
                    287:       strncasecmp (deb, "min-width", 9) &&
                    288:       strncasecmp (deb, "orphans", 7) &&
                    289:       strncasecmp (deb, "outline-color", 13) &&
                    290:       strncasecmp (deb, "outline-style", 13) &&
                    291:       strncasecmp (deb, "outline-width", 13) &&
                    292:       strncasecmp (deb, "outline", 7) &&
                    293:       strncasecmp (deb, "overflow", 8) &&
                    294:       strncasecmp (deb, "quotes", 6) &&
                    295:       strncasecmp (deb, "table-layout", 12) &&
1.259     vatton    296:       strncasecmp (deb, "text-shadow", 11) &&
1.234     vatton    297:       strncasecmp (deb, "visibility", 10) &&
1.258     vatton    298:       strncasecmp (deb, "widows", 6))
1.205     quint     299:     CSSPrintError ("CSS property ignored:", deb);
1.86      cvs       300:   *ptr = c;
1.288     vatton    301: #endif /* IV */
1.86      cvs       302:   return (ptr);
                    303: }
                    304: 
                    305: /*----------------------------------------------------------------------
1.168     vatton    306:    SkipValue
                    307:    skips the value and display an error message if msg is not NULL
1.1       cvs       308:   ----------------------------------------------------------------------*/
1.168     vatton    309: static char *SkipValue (char *msg, char *ptr)
1.1       cvs       310: {
1.86      cvs       311:   char       *deb;
                    312:   char        c;
                    313: 
                    314:   deb = ptr;
1.301     vatton    315:   while (*ptr != EOS && *ptr != ';' && *ptr != '}' && *ptr != '}')
1.133     vatton    316:     {
                    317:       if (*ptr == '"' && (ptr == deb || ptr[-1] != '\\'))
                    318:        {
                    319:          /* skip to the end of the string "..." */
                    320:          ptr++;
1.184     vatton    321:          while (*ptr != '"' || (ptr[0] == '"' && ptr[-1] == '\\'))
1.133     vatton    322:            ptr++;
                    323:        }
                    324:       ptr++;
                    325:     }
1.95      cvs       326:   /* print the skipped property */
1.86      cvs       327:   c = *ptr;
                    328:   *ptr = EOS;
1.168     vatton    329:   if (msg && *deb != EOS && *deb != ',')
                    330:     CSSPrintError (msg, deb);
1.86      cvs       331:   *ptr = c;
1.1       cvs       332:   return (ptr);
                    333: }
                    334: 
                    335: /*----------------------------------------------------------------------
1.64      cvs       336:    ParseNumber:                                                  
                    337:    parse a number and returns the corresponding value.
1.1       cvs       338:   ----------------------------------------------------------------------*/
1.79      cvs       339: char *ParseNumber (char *cssRule, PresentationValue *pval)
1.1       cvs       340: {
                    341:   int                 val = 0;
                    342:   int                 minus = 0;
                    343:   int                 valid = 0;
                    344:   int                 f = 0;
1.14      cvs       345:   ThotBool            real = FALSE;
1.1       cvs       346: 
1.184     vatton    347:   pval->typed_data.unit = UNIT_REL;
1.1       cvs       348:   pval->typed_data.real = FALSE;
1.82      cvs       349:   cssRule = SkipBlanksAndComments (cssRule);
                    350:   if (*cssRule == '-')
1.1       cvs       351:     {
                    352:       minus = 1;
                    353:       cssRule++;
1.82      cvs       354:       cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs       355:     }
                    356: 
1.82      cvs       357:   if (*cssRule == '+')
1.1       cvs       358:     {
                    359:       cssRule++;
1.82      cvs       360:       cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs       361:     }
                    362: 
1.82      cvs       363:   while ((*cssRule >= '0') && (*cssRule <= '9'))
1.1       cvs       364:     {
                    365:       val *= 10;
1.82      cvs       366:       val += *cssRule - '0';
1.1       cvs       367:       cssRule++;
                    368:       valid = 1;
                    369:     }
                    370: 
1.82      cvs       371:   if (*cssRule == '.')
1.1       cvs       372:     {
                    373:       real = TRUE;
                    374:       f = val;
                    375:       val = 0;
                    376:       cssRule++;
                    377:       /* keep only 3 digits */
1.82      cvs       378:       if (*cssRule >= '0' && *cssRule <= '9')
1.1       cvs       379:        {
1.82      cvs       380:          val = (*cssRule - '0') * 100;
1.1       cvs       381:          cssRule++;
1.82      cvs       382:          if (*cssRule >= '0' && *cssRule <= '9')
1.1       cvs       383:            {
1.82      cvs       384:              val += (*cssRule - '0') * 10;
1.1       cvs       385:              cssRule++;
1.82      cvs       386:              if ((*cssRule >= '0') && (*cssRule <= '9'))
1.1       cvs       387:                {
1.82      cvs       388:                  val += *cssRule - '0';
1.1       cvs       389:                  cssRule++;
                    390:                }
                    391:            }
                    392: 
1.82      cvs       393:          while (*cssRule >= '0' && *cssRule <= '9')
1.1       cvs       394:            cssRule++;
                    395:          valid = 1;
                    396:        }
                    397:     }
                    398: 
                    399:   if (!valid)
                    400:     {
1.184     vatton    401:       pval->typed_data.unit = UNIT_INVALID;
1.1       cvs       402:       pval->typed_data.value = 0;
                    403:     }
                    404:   else
                    405:     {
                    406:       pval->typed_data.real = real;
                    407:       if (real)
                    408:        {
                    409:          if (minus)
                    410:            pval->typed_data.value = -(f * 1000 + val);
                    411:          else
                    412:            pval->typed_data.value = f * 1000 + val;
                    413:        }
                    414:       else
                    415:        {
                    416:          if (minus)
                    417:            pval->typed_data.value = -val;
                    418:          else
                    419:            pval->typed_data.value = val;
                    420:        }
1.64      cvs       421:     }
                    422:   return (cssRule);
                    423: }
1.195     vatton    424: 
1.155     cheyroul  425: /*----------------------------------------------------------------------
1.64      cvs       426:    ParseCSSUnit:                                                  
                    427:    parse a CSS Unit substring and returns the corresponding      
                    428:    value and its unit.                                           
                    429:   ----------------------------------------------------------------------*/
1.82      cvs       430: char *ParseCSSUnit (char *cssRule, PresentationValue *pval)
1.64      cvs       431: {
                    432:   unsigned int        uni;
                    433: 
1.184     vatton    434:   pval->typed_data.unit = UNIT_REL;
1.64      cvs       435:   cssRule = ParseNumber (cssRule, pval);
1.184     vatton    436:   if (pval->typed_data.unit == UNIT_INVALID)
1.64      cvs       437:       cssRule = SkipWord (cssRule);
                    438:   else
                    439:     {
1.82      cvs       440:       cssRule = SkipBlanksAndComments (cssRule);
1.231     vatton    441:       uni = 0;
                    442:       while (CSSUnitNames[uni].sign)
1.64      cvs       443:        {
1.82      cvs       444:          if (!strncasecmp (CSSUnitNames[uni].sign, cssRule,
                    445:                             strlen (CSSUnitNames[uni].sign)))
1.64      cvs       446:            {
                    447:              pval->typed_data.unit = CSSUnitNames[uni].unit;
1.82      cvs       448:              return (cssRule + strlen (CSSUnitNames[uni].sign));
1.64      cvs       449:            }
1.231     vatton    450:          else
                    451:            uni++;
1.64      cvs       452:        }
                    453:       /* not in the list of predefined units */
1.184     vatton    454:       pval->typed_data.unit = UNIT_BOX;
1.1       cvs       455:     }
                    456:   return (cssRule);
                    457: }
                    458: 
1.43      cvs       459: /*----------------------------------------------------------------------
1.239     vatton    460:    ParseClampedUnit:                                                  
                    461:    parse a CSS Unit substring and returns the corresponding value and unit.
                    462:    [0,1]
                    463:   ----------------------------------------------------------------------*/
                    464: char *ParseClampedUnit (char *cssRule, PresentationValue *pval)
                    465: {
1.251     vatton    466:   char           *p;
                    467: 
                    468:   p = cssRule;
1.239     vatton    469:   cssRule = ParseNumber (cssRule, pval);
1.301     vatton    470:   if (*cssRule != EOS && *cssRule != SPACE && *cssRule != ';' && *cssRule != '}')
1.239     vatton    471:     {
1.251     vatton    472:       cssRule++;
1.239     vatton    473:       pval->typed_data.unit = UNIT_REL;
                    474:       if (pval->typed_data.value > 100)
                    475:        pval->typed_data.value = 1000;
                    476:       else
                    477:        pval->typed_data.value *= 10;
1.251     vatton    478:       CSSParseError ("Invalid value", p, cssRule);
1.239     vatton    479:     }
                    480:   else
                    481:     {
                    482:       pval->typed_data.unit = UNIT_REL;
                    483:       if (pval->typed_data.real)
                    484:        pval->typed_data.real = FALSE;
                    485:       else if (pval->typed_data.value > 1)
1.251     vatton    486:        {
                    487:          pval->typed_data.value = 1000;
                    488:          CSSParseError ("Invalid value", p, cssRule);
                    489:        }
                    490:       else if (pval->typed_data.value < 0)
                    491:        {
                    492:          pval->typed_data.value = 0;
                    493:          CSSParseError ("Invalid value", p, cssRule);
                    494:        }
1.239     vatton    495:       else
                    496:        pval->typed_data.value *= 1000;
                    497:     }
                    498:   pval->data = pval->typed_data.value;
                    499:   return (cssRule);
                    500: }
                    501: 
                    502: 
                    503: /*----------------------------------------------------------------------
1.288     vatton    504:    ParseABorderValue                                       
1.43      cvs       505:   ----------------------------------------------------------------------*/
1.288     vatton    506: static char *ParseABorderValue (char *cssRule, PresentationValue *border)
1.43      cvs       507: {
1.288     vatton    508:   char             *ptr = cssRule;
1.168     vatton    509: 
1.43      cvs       510:   /* first parse the attribute string */
                    511:    border->typed_data.value = 0;
1.184     vatton    512:    border->typed_data.unit = UNIT_INVALID;
1.43      cvs       513:    border->typed_data.real = FALSE;
1.82      cvs       514:    if (!strncasecmp (cssRule, "thin", 4))
1.43      cvs       515:      {
1.184     vatton    516:        border->typed_data.unit = UNIT_PX;
1.43      cvs       517:        border->typed_data.value = 1;
1.288     vatton    518:        cssRule += 4;
1.43      cvs       519:      }
1.82      cvs       520:    else if (!strncasecmp (cssRule, "medium", 6))
1.43      cvs       521:      {
1.184     vatton    522:        border->typed_data.unit = UNIT_PX;
1.43      cvs       523:        border->typed_data.value = 3;
1.288     vatton    524:        cssRule += 6;
1.43      cvs       525:      }
1.82      cvs       526:    else if (!strncasecmp (cssRule, "thick", 5))
1.43      cvs       527:      {
1.184     vatton    528:        border->typed_data.unit = UNIT_PX;
1.43      cvs       529:        border->typed_data.value = 5;
1.288     vatton    530:        cssRule += 5;
1.43      cvs       531:      }
1.110     vatton    532:    else if (isdigit (*cssRule) || *cssRule == '.')
1.166     vatton    533:      {
                    534:        cssRule = ParseCSSUnit (cssRule, border);
1.168     vatton    535:        if (border->typed_data.value == 0)
1.184     vatton    536:         border->typed_data.unit = UNIT_PX;
                    537:        else if (border->typed_data.unit == UNIT_INVALID ||
1.244     vatton    538:                border->typed_data.unit == UNIT_BOX ||
                    539:                border->typed_data.unit == UNIT_PERCENT)
1.168     vatton    540:         {
1.184     vatton    541:           border->typed_data.unit = UNIT_INVALID;
1.168     vatton    542:           border->typed_data.value = 0;
                    543:           CSSParseError ("Invalid border-width value", ptr, cssRule);
                    544:         }
1.166     vatton    545:      }
1.43      cvs       546:    return (cssRule);
                    547: }
                    548: 
1.288     vatton    549: 
                    550: /*----------------------------------------------------------------------
1.43      cvs       551:    ParseBorderStyle                                      
                    552:   ----------------------------------------------------------------------*/
1.79      cvs       553: static char *ParseBorderStyle (char *cssRule, PresentationValue *border)
1.43      cvs       554: {
1.288     vatton    555:   char *ptr = cssRule;
                    556: 
1.43      cvs       557:   /* first parse the attribute string */
                    558:    border->typed_data.value = 0;
1.184     vatton    559:    border->typed_data.unit = UNIT_PX;
1.43      cvs       560:    border->typed_data.real = FALSE;
1.82      cvs       561:    if (!strncasecmp (cssRule, "none", 4))
1.288     vatton    562:      {
1.184     vatton    563:      border->typed_data.value = BorderStyleNone;
1.288     vatton    564:      cssRule += 4;
                    565:      }
1.82      cvs       566:    else if (!strncasecmp (cssRule, "hidden", 6))
1.288     vatton    567:      {
1.184     vatton    568:      border->typed_data.value = BorderStyleHidden;
1.288     vatton    569:      cssRule += 6;
                    570:      }
1.82      cvs       571:    else if (!strncasecmp (cssRule, "dotted", 6))
1.288     vatton    572:      {
                    573:      cssRule += 6;
1.184     vatton    574:      border->typed_data.value = BorderStyleDotted;
1.288     vatton    575:      }
1.82      cvs       576:    else if (!strncasecmp (cssRule, "dashed", 6))
1.288     vatton    577:      {
1.184     vatton    578:      border->typed_data.value = BorderStyleDashed;
1.288     vatton    579:      cssRule += 6;
                    580:      }
1.82      cvs       581:    else if (!strncasecmp (cssRule, "solid", 5))
1.288     vatton    582:      {
1.184     vatton    583:      border->typed_data.value = BorderStyleSolid;
1.288     vatton    584:      cssRule += 5;
                    585:      }
1.82      cvs       586:    else if (!strncasecmp (cssRule, "double", 6))
1.288     vatton    587:      {
1.184     vatton    588:      border->typed_data.value = BorderStyleDouble;
1.288     vatton    589:      cssRule += 6;
                    590:      }
1.82      cvs       591:    else if (!strncasecmp (cssRule, "groove", 6))
1.288     vatton    592:      {
1.184     vatton    593:      border->typed_data.value = BorderStyleGroove;
1.288     vatton    594:      cssRule += 6;
                    595:      }
1.82      cvs       596:    else if (!strncasecmp (cssRule, "ridge", 5))
1.288     vatton    597:      {
1.184     vatton    598:      border->typed_data.value = BorderStyleRidge;
1.288     vatton    599:      cssRule += 5;
                    600:      }
1.82      cvs       601:    else if (!strncasecmp (cssRule, "inset", 5))
1.288     vatton    602:      {
1.184     vatton    603:      border->typed_data.value = BorderStyleInset;
1.288     vatton    604:      cssRule += 5;
                    605:      }
1.82      cvs       606:    else if (!strncasecmp (cssRule, "outset", 6))
1.288     vatton    607:      {
1.184     vatton    608:      border->typed_data.value = BorderStyleOutset;
1.288     vatton    609:       cssRule += 6;
                    610:     }
1.43      cvs       611:    else
1.44      cvs       612:      {
                    613:        /* invalid style */
1.184     vatton    614:        border->typed_data.unit = UNIT_INVALID;
1.44      cvs       615:        return (cssRule);
                    616:      }
1.43      cvs       617:    /* the value is parsed now */
1.288     vatton    618:    /*cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid border-style value");*/
1.43      cvs       619:    return (cssRule);
                    620: }
                    621: 
                    622: /*----------------------------------------------------------------------
1.59      cvs       623:    ParseCSSColor: parse a CSS color attribute string    
1.43      cvs       624:    we expect the input string describing the attribute to be     
                    625:    either a color name, a 3 tuple or an hexadecimal encoding.    
                    626:    The color used will be approximed from the current color      
                    627:    table                                                         
                    628:   ----------------------------------------------------------------------*/
1.79      cvs       629: static char *ParseCSSColor (char *cssRule, PresentationValue * val)
1.43      cvs       630: {
1.79      cvs       631:   char               *ptr;
1.43      cvs       632:   unsigned short      redval = (unsigned short) -1;
                    633:   unsigned short      greenval = 0;    /* composant of each RGB       */
                    634:   unsigned short      blueval = 0;     /* default to red if unknown ! */
                    635:   int                 best = 0;        /* best color in list found */
                    636: 
1.82      cvs       637:   cssRule = SkipBlanksAndComments (cssRule);
1.184     vatton    638:   val->typed_data.unit = UNIT_INVALID;
1.43      cvs       639:   val->typed_data.real = FALSE;
                    640:   val->typed_data.value = 0;
1.57      cvs       641:   ptr = TtaGiveRGB (cssRule, &redval, &greenval, &blueval);
1.292     vatton    642:   if (!strncasecmp (cssRule, "InactiveCaptionText", 19))
                    643:     {
                    644:       cssRule += 19;
                    645:     }
                    646:   else if (!strncasecmp (cssRule, "ThreeDLightShadow", 17))
                    647:     {
                    648:       cssRule += 17;
                    649:     }
                    650:   else if (!strncasecmp (cssRule, "ThreeDDarkShadow", 16))
                    651:     {
                    652:       cssRule += 16;
                    653:     }
                    654:   else if (!strncasecmp (cssRule, "ButtonHighlight", 15) ||
                    655:           !strncasecmp (cssRule, "InactiveCaption", 15) ||
                    656:           !strncasecmp (cssRule, "ThreeDHighlight", 15))
                    657:     {
                    658:       cssRule += 15;
                    659:     }
                    660:   else if (!strncasecmp (cssRule, "InactiveBorder", 14) ||
                    661:           !strncasecmp (cssRule, "InfoBackground", 14))
                    662:     {
                    663:       cssRule += 14;
                    664:     }
                    665:   else if (!strncasecmp (cssRule, "ActiveCaption", 13) ||
                    666:           !strncasecmp (cssRule, "HighlightText", 13))
                    667:     {
                    668:       cssRule += 13;
                    669:     }
                    670:   else if (!strncasecmp (cssRule, "ActiveBorder", 12) ||
                    671:           !strncasecmp (cssRule, "AppWorkspace", 12) ||
                    672:           !strncasecmp (cssRule, "ButtonShadow", 12) ||
                    673:           !strncasecmp (cssRule, "ThreeDShadow", 12))
                    674:     {
                    675:       cssRule += 12;
                    676:     }
                    677:   else if (!strncasecmp (cssRule, "CaptionText", 11) ||
                    678:           !strncasecmp (cssRule, "WindowFrame", 11))
                    679:     {
                    680:       cssRule += 11;
                    681:     }
                    682:   else if (!strncasecmp (cssRule, "Background", 10) ||
                    683:           !strncasecmp (cssRule, "ButtonFace", 10) ||
                    684:           !strncasecmp (cssRule, "ButtonText", 10) ||
                    685:           !strncasecmp (cssRule, "ThreeDFace", 10) ||
                    686:           !strncasecmp (cssRule, "WindowText", 10))
                    687:     {
                    688:       cssRule += 10;
                    689:     }
                    690:   else if (!strncasecmp (cssRule, "Highlight", 9) ||
                    691:           !strncasecmp (cssRule, "Scrollbar", 9))
                    692:     {
                    693:       cssRule += 9;
                    694:     }
                    695:   else if (!strncasecmp (cssRule, "GrayText", 8) ||
                    696:           !strncasecmp (cssRule, "InfoText", 8) ||
                    697:           !strncasecmp (cssRule, "MenuText", 8))
                    698:     {
                    699:       cssRule += 8;
                    700:     }
                    701:   else if (!strncasecmp (cssRule, "Window", 6))
                    702:     {
                    703:       cssRule += 6;
                    704:     }
                    705:   else if (!strncasecmp (cssRule, "Menu", 5))
                    706:     {
                    707:       cssRule += 5;
                    708:     }
1.293     quint     709:   else if (!strncasecmp (cssRule, "inherit", 7))
                    710:     {
                    711:       val->typed_data.unit = VALUE_INHERIT;
                    712:       cssRule += 7;
                    713:     }
1.292     vatton    714: 
1.57      cvs       715:   if (ptr == cssRule)
1.43      cvs       716:     {
1.168     vatton    717:       cssRule = SkipWord (cssRule);
                    718:       CSSParseError ("Invalid color value", ptr, cssRule);
1.43      cvs       719:       val->typed_data.value = 0;
1.184     vatton    720:       val->typed_data.unit = UNIT_INVALID;
1.43      cvs       721:     }
1.293     quint     722:   else if (val->typed_data.unit != VALUE_INHERIT)
1.43      cvs       723:     {
                    724:       best = TtaGetThotColor (redval, greenval, blueval);
                    725:       val->typed_data.value = best;
1.184     vatton    726:       val->typed_data.unit = UNIT_REL;
1.57      cvs       727:       cssRule = ptr;
1.43      cvs       728:     }
                    729:   val->typed_data.real = FALSE;
1.262     vatton    730:   cssRule = SkipBlanksAndComments (cssRule);
1.65      cvs       731:   return (cssRule);
1.43      cvs       732: }
1.1       cvs       733: 
                    734: /*----------------------------------------------------------------------
1.231     vatton    735:   CheckImportantRule updates the field important of the context and
                    736:   the line number.
1.117     vatton    737:   ----------------------------------------------------------------------*/
                    738: static char *CheckImportantRule (char *cssRule, PresentationContext context)
                    739: {
1.276     vatton    740:   PresentationContextBlock dummyctxt;
                    741: 
                    742:   if (context == NULL)
                    743:     /* no context provided */
                    744:     context = &dummyctxt;
                    745: 
1.117     vatton    746:   cssRule = SkipBlanksAndComments (cssRule);
1.231     vatton    747:   /* update the line number */
                    748:   context->cssLine = LineNumber + NewLineSkipped;
1.120     vatton    749:   if (*cssRule != '!')
                    750:     context->important = FALSE;
                    751:   else
1.117     vatton    752:     {
1.120     vatton    753:       cssRule++;
                    754:       cssRule = SkipBlanksAndComments (cssRule);
                    755:       if (!strncasecmp (cssRule, "important", 9))
                    756:        {
                    757:          context->important = TRUE;
                    758:          cssRule += 9;
                    759:        }
                    760:       else
                    761:        context->important = FALSE;
1.117     vatton    762:     }
                    763:   return (cssRule);
                    764: }
                    765: 
                    766: /*----------------------------------------------------------------------
1.59      cvs       767:    ParseCSSBorderTopWidth: parse a CSS BorderTopWidth
1.1       cvs       768:    attribute string.                                          
                    769:   ----------------------------------------------------------------------*/
1.79      cvs       770: static char *ParseCSSBorderTopWidth (Element element, PSchema tsch,
                    771:                                       PresentationContext context, 
                    772:                                       char *cssRule, CSSInfoPtr css,
                    773:                                       ThotBool isHTML)
1.1       cvs       774: {
1.41      cvs       775:   PresentationValue   border;
                    776:   
1.82      cvs       777:   cssRule = SkipBlanksAndComments (cssRule);
1.288     vatton    778:   cssRule = ParseABorderValue (cssRule, &border);
1.295     vatton    779:   /* check if it's an important rule */
                    780:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton    781:   if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.44      cvs       782:     {
                    783:       TtaSetStylePresentation (PRBorderTopWidth, element, tsch, context, border);
                    784:       border.typed_data.value = 1;
1.184     vatton    785:       border.typed_data.unit = UNIT_REL;
1.44      cvs       786:     }
1.1       cvs       787:   return (cssRule);
                    788: }
                    789: 
                    790: /*----------------------------------------------------------------------
1.59      cvs       791:    ParseCSSBorderBottomWidth: parse a CSS BorderBottomWidth
1.1       cvs       792:    attribute string.                                          
                    793:   ----------------------------------------------------------------------*/
1.79      cvs       794: static char *ParseCSSBorderBottomWidth (Element element, PSchema tsch,
                    795:                                          PresentationContext context,
                    796:                                          char *cssRule, CSSInfoPtr css,
                    797:                                          ThotBool isHTML)
1.1       cvs       798: {
1.41      cvs       799:   PresentationValue   border;
                    800:   
1.82      cvs       801:   cssRule = SkipBlanksAndComments (cssRule);
1.41      cvs       802:   /* first parse the attribute string */
1.288     vatton    803:   cssRule = ParseABorderValue (cssRule, &border);
1.295     vatton    804:   /* check if it's an important rule */
                    805:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton    806:   if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.44      cvs       807:     {
                    808:       TtaSetStylePresentation (PRBorderBottomWidth, element, tsch, context, border);
                    809:       border.typed_data.value = 1;
1.184     vatton    810:       border.typed_data.unit = UNIT_REL;
1.44      cvs       811:     }
1.1       cvs       812:   return (cssRule);
                    813: }
                    814: 
                    815: /*----------------------------------------------------------------------
1.59      cvs       816:    ParseCSSBorderLeftWidth: parse a CSS BorderLeftWidth
1.1       cvs       817:    attribute string.                                          
                    818:   ----------------------------------------------------------------------*/
1.79      cvs       819: static char *ParseCSSBorderLeftWidth (Element element, PSchema tsch,
                    820:                                        PresentationContext context,
                    821:                                        char *cssRule, CSSInfoPtr css,
                    822:                                        ThotBool isHTML)
1.1       cvs       823: {
1.41      cvs       824:   PresentationValue   border;
                    825:   
1.82      cvs       826:   cssRule = SkipBlanksAndComments (cssRule);
1.41      cvs       827:   /* first parse the attribute string */
1.288     vatton    828:   cssRule = ParseABorderValue (cssRule, &border);
1.295     vatton    829:   /* check if it's an important rule */
                    830:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton    831:   if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.44      cvs       832:     {
                    833:       TtaSetStylePresentation (PRBorderLeftWidth, element, tsch, context, border);
                    834:       border.typed_data.value = 1;
1.184     vatton    835:       border.typed_data.unit = UNIT_REL;
1.44      cvs       836:     }
1.1       cvs       837:   return (cssRule);
                    838: }
                    839: 
                    840: /*----------------------------------------------------------------------
1.59      cvs       841:    ParseCSSBorderRightWidth: parse a CSS BorderRightWidth
1.1       cvs       842:    attribute string.                                          
                    843:   ----------------------------------------------------------------------*/
1.79      cvs       844: static char *ParseCSSBorderRightWidth (Element element, PSchema tsch,
                    845:                                         PresentationContext context,
                    846:                                         char *cssRule, CSSInfoPtr css,
                    847:                                         ThotBool isHTML)
1.1       cvs       848: {
1.41      cvs       849:   PresentationValue   border;
                    850:   
1.82      cvs       851:   cssRule = SkipBlanksAndComments (cssRule);
1.41      cvs       852:   /* first parse the attribute string */
1.288     vatton    853:   cssRule = ParseABorderValue (cssRule, &border);
1.295     vatton    854:   /* check if it's an important rule */
                    855:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton    856:   if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.44      cvs       857:     {
                    858:       TtaSetStylePresentation (PRBorderRightWidth, element, tsch, context, border);
                    859:       border.typed_data.value = 1;
1.184     vatton    860:       border.typed_data.unit = UNIT_REL;
1.44      cvs       861:     }
1.1       cvs       862:   return (cssRule);
                    863: }
                    864: 
                    865: /*----------------------------------------------------------------------
1.59      cvs       866:    ParseCSSBorderWidth: parse a CSS BorderWidth
1.1       cvs       867:    attribute string.                                          
                    868:   ----------------------------------------------------------------------*/
1.79      cvs       869: static char *ParseCSSBorderWidth (Element element, PSchema tsch,
                    870:                                    PresentationContext context,
                    871:                                    char *cssRule, CSSInfoPtr css,
                    872:                                    ThotBool isHTML)
1.1       cvs       873: {
1.79      cvs       874:   char *ptrT, *ptrR, *ptrB, *ptrL;
1.93      vatton    875:   int   skippedNL;
1.41      cvs       876: 
1.82      cvs       877:   ptrT = SkipBlanksAndComments (cssRule);
1.42      cvs       878:   /* First parse Border-Top */
                    879:   ptrR = ParseCSSBorderTopWidth (element, tsch, context, ptrT, css, isHTML);
1.82      cvs       880:   ptrR = SkipBlanksAndComments (ptrR);
1.301     vatton    881:   if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.42      cvs       882:     {
1.93      vatton    883:       skippedNL = NewLineSkipped;
1.42      cvs       884:       cssRule = ptrR;
                    885:       /* apply the Border-Top to all */
                    886:       ptrR = ParseCSSBorderRightWidth (element, tsch, context, ptrT, css, isHTML);
1.93      vatton    887:       NewLineSkipped = skippedNL;
1.42      cvs       888:       ptrR = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
1.93      vatton    889:       NewLineSkipped = skippedNL;
1.42      cvs       890:       ptrR = ParseCSSBorderLeftWidth (element, tsch, context, ptrT, css, isHTML);
                    891:     }
                    892:   else
                    893:     {
                    894:       /* parse Border-Right */
                    895:       ptrB = ParseCSSBorderRightWidth (element, tsch, context, ptrR, css, isHTML);
1.82      cvs       896:       ptrB = SkipBlanksAndComments (ptrB);
1.301     vatton    897:       if (*ptrB == ';' || *ptrB == '}' || *ptrB == EOS || *ptrB == ',')
1.42      cvs       898:        {
1.93      vatton    899:          skippedNL = NewLineSkipped;
1.42      cvs       900:          cssRule = ptrB;
                    901:          /* apply the Border-Top to Border-Bottom */
                    902:          ptrB = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
1.93      vatton    903:          NewLineSkipped = skippedNL;
1.42      cvs       904:          /* apply the Border-Right to Border-Left */
                    905:          ptrB = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
                    906:        }
                    907:       else
                    908:        {
                    909:          /* parse Border-Bottom */
                    910:          ptrL = ParseCSSBorderBottomWidth (element, tsch, context, ptrB, css, isHTML);
1.82      cvs       911:          ptrL = SkipBlanksAndComments (ptrL);
1.301     vatton    912:          if (*ptrL == ';' || *ptrL == '}' || *ptrL == EOS || *ptrL == ',')
1.42      cvs       913:            {
                    914:              cssRule = ptrL;
                    915:              /* apply the Border-Right to Border-Left */
                    916:              ptrL = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
                    917:            }
                    918:          else
                    919:            /* parse Border-Left */
                    920:            cssRule = ParseCSSBorderLeftWidth (element, tsch, context, ptrL, css, isHTML);
1.82      cvs       921:          cssRule = SkipBlanksAndComments (cssRule);
1.42      cvs       922:        }
                    923:     }
1.1       cvs       924:   return (cssRule);
                    925: }
                    926: 
                    927: /*----------------------------------------------------------------------
1.59      cvs       928:    ParseCSSBorderColorTop: parse a CSS BorderColorTop
1.1       cvs       929:    attribute string.                                          
                    930:   ----------------------------------------------------------------------*/
1.79      cvs       931: static char *ParseCSSBorderColorTop (Element element, PSchema tsch,
                    932:                                     PresentationContext context,
                    933:                                     char *cssRule, CSSInfoPtr css,
                    934:                                     ThotBool isHTML)
1.1       cvs       935: {
1.117     vatton    936:   PresentationValue   best;
1.43      cvs       937: 
1.234     vatton    938:   if (!strncasecmp (cssRule, "transparent", 11))
                    939:     {
                    940:       best.typed_data.value = -2;  /* -2 means transparent */
                    941:       best.typed_data.unit = UNIT_REL;
                    942:       cssRule = SkipWord (cssRule);
                    943:     }
                    944:   else
                    945:     cssRule = ParseCSSColor (cssRule, &best);
1.295     vatton    946:   /* check if it's an important rule */
                    947:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton    948:   if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117     vatton    949:     {
                    950:       /* install the new presentation */
                    951:       TtaSetStylePresentation (PRBorderTopColor, element, tsch, context, best);
                    952:     }
                    953:   return (cssRule);
1.1       cvs       954: }
                    955: 
                    956: /*----------------------------------------------------------------------
1.59      cvs       957:    ParseCSSBorderColorLeft: parse a CSS BorderColorLeft
1.42      cvs       958:    attribute string.                                          
                    959:   ----------------------------------------------------------------------*/
1.79      cvs       960: static char *ParseCSSBorderColorLeft (Element element, PSchema tsch,
                    961:                                      PresentationContext context,
                    962:                                      char *cssRule, CSSInfoPtr css,
                    963:                                      ThotBool isHTML)
1.42      cvs       964: {
1.117     vatton    965:   PresentationValue   best;
                    966:   
1.234     vatton    967:   if (!strncasecmp (cssRule, "transparent", 11))
                    968:     {
                    969:       best.typed_data.value = -2;  /* -2 means transparent */
                    970:       best.typed_data.unit = UNIT_REL;
                    971:       cssRule = SkipWord (cssRule);
                    972:     }
                    973:   else
                    974:     cssRule = ParseCSSColor (cssRule, &best);
1.295     vatton    975:   /* check if it's an important rule */
                    976:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton    977:   if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117     vatton    978:     {
                    979:       /* install the new presentation */
                    980:       TtaSetStylePresentation (PRBorderLeftColor, element, tsch, context, best);
                    981:     }
                    982:   return (cssRule);
1.42      cvs       983: }
                    984: 
                    985: /*----------------------------------------------------------------------
1.59      cvs       986:    ParseCSSBorderColorBottom: parse a CSS BorderColorBottom
1.42      cvs       987:    attribute string.                                          
                    988:   ----------------------------------------------------------------------*/
1.79      cvs       989: static char *ParseCSSBorderColorBottom (Element element, PSchema tsch,
                    990:                                        PresentationContext context,
                    991:                                        char *cssRule, CSSInfoPtr css,
                    992:                                        ThotBool isHTML)
1.42      cvs       993: {
1.117     vatton    994:   PresentationValue   best;
1.43      cvs       995: 
1.234     vatton    996:   if (!strncasecmp (cssRule, "transparent", 11))
                    997:     {
                    998:       best.typed_data.value = -2;  /* -2 means transparent */
                    999:       best.typed_data.unit = UNIT_REL;
                   1000:       cssRule = SkipWord (cssRule);
                   1001:     }
                   1002:   else
                   1003:     cssRule = ParseCSSColor (cssRule, &best);
1.295     vatton   1004:   /* check if it's an important rule */
                   1005:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton   1006:   if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117     vatton   1007:     {
                   1008:       /* install the new presentation */
                   1009:       TtaSetStylePresentation (PRBorderBottomColor, element, tsch, context, best);
                   1010:     }
1.65      cvs      1011:    return (cssRule);
1.42      cvs      1012: }
                   1013: 
                   1014: /*----------------------------------------------------------------------
1.59      cvs      1015:    ParseCSSBorderColorRight: parse a CSS BorderColorRight
1.1       cvs      1016:    attribute string.                                          
                   1017:   ----------------------------------------------------------------------*/
1.79      cvs      1018: static char *ParseCSSBorderColorRight (Element element, PSchema tsch,
                   1019:                                       PresentationContext context,
                   1020:                                       char *cssRule, CSSInfoPtr css,
                   1021:                                       ThotBool isHTML)
1.1       cvs      1022: {
1.117     vatton   1023:   PresentationValue   best;
1.43      cvs      1024: 
1.234     vatton   1025:   if (!strncasecmp (cssRule, "transparent", 11))
                   1026:     {
                   1027:       best.typed_data.value = -2;  /* -2 means transparent */
                   1028:       best.typed_data.unit = UNIT_REL;
                   1029:       cssRule = SkipWord (cssRule);
                   1030:     }
                   1031:   else
                   1032:     cssRule = ParseCSSColor (cssRule, &best);
1.295     vatton   1033:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton   1034:   if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117     vatton   1035:     {
                   1036:       /* check if it's an important rule */
                   1037:       /* install the new presentation */
                   1038:       TtaSetStylePresentation (PRBorderRightColor, element, tsch, context, best);
                   1039:     }
                   1040:   return (cssRule);
1.1       cvs      1041: }
                   1042: 
                   1043: /*----------------------------------------------------------------------
1.59      cvs      1044:    ParseCSSBorderColor: parse a CSS border-color        
1.42      cvs      1045:    attribute string.                                          
                   1046:   ----------------------------------------------------------------------*/
1.79      cvs      1047: static char *ParseCSSBorderColor (Element element, PSchema tsch,
                   1048:                                  PresentationContext context,
                   1049:                                  char *cssRule, CSSInfoPtr css,
                   1050:                                  ThotBool isHTML)
1.42      cvs      1051: {
1.79      cvs      1052:   char *ptrT, *ptrR, *ptrB, *ptrL;
1.93      vatton   1053:   int   skippedNL;
1.42      cvs      1054: 
1.82      cvs      1055:   ptrT = SkipBlanksAndComments (cssRule);
1.42      cvs      1056:   /* First parse Border-Top */
1.43      cvs      1057:   ptrR = ParseCSSBorderColorTop (element, tsch, context, ptrT, css, isHTML);
1.82      cvs      1058:   ptrR = SkipBlanksAndComments (ptrR);
1.301     vatton   1059:   if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.42      cvs      1060:     {
1.93      vatton   1061:       skippedNL = NewLineSkipped;
1.42      cvs      1062:       cssRule = ptrR;
                   1063:       /* apply the Border-Top to all */
1.43      cvs      1064:       ptrR = ParseCSSBorderColorRight (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   1065:          NewLineSkipped = skippedNL;
1.43      cvs      1066:       ptrR = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   1067:          NewLineSkipped = skippedNL;
1.43      cvs      1068:       ptrR = ParseCSSBorderColorLeft (element, tsch, context, ptrT, css, isHTML);
1.42      cvs      1069:     }
                   1070:   else
                   1071:     {
                   1072:       /* parse Border-Right */
1.43      cvs      1073:       ptrB = ParseCSSBorderColorRight (element, tsch, context, ptrR, css, isHTML);
1.82      cvs      1074:       ptrB = SkipBlanksAndComments (ptrB);
1.301     vatton   1075:       if (*ptrB == ';' || *ptrB == '}' || *ptrB == EOS || *ptrB == ',')
1.42      cvs      1076:        {
1.93      vatton   1077:          skippedNL = NewLineSkipped;
1.42      cvs      1078:          cssRule = ptrB;
                   1079:          /* apply the Border-Top to Border-Bottom */
1.43      cvs      1080:          ptrB = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   1081:          NewLineSkipped = skippedNL;
1.42      cvs      1082:          /* apply the Border-Right to Border-Left */
1.43      cvs      1083:          ptrB = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1.42      cvs      1084:        }
                   1085:       else
                   1086:        {
1.93      vatton   1087:          skippedNL = NewLineSkipped;
1.42      cvs      1088:          /* parse Border-Bottom */
1.43      cvs      1089:          ptrL = ParseCSSBorderColorBottom (element, tsch, context, ptrB, css, isHTML);
1.93      vatton   1090:          NewLineSkipped = skippedNL;
1.82      cvs      1091:          ptrL = SkipBlanksAndComments (ptrL);
1.301     vatton   1092:          if (*ptrL == ';' || *ptrL == '}' || *ptrL == EOS || *ptrL == ',')
1.42      cvs      1093:            {
                   1094:              cssRule = ptrL;
                   1095:              /* apply the Border-Right to Border-Left */
1.43      cvs      1096:              ptrL = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1.42      cvs      1097:            }
                   1098:          else
                   1099:            /* parse Border-Left */
1.43      cvs      1100:            cssRule = ParseCSSBorderColorLeft (element, tsch, context, ptrL, css, isHTML);
1.82      cvs      1101:          cssRule = SkipBlanksAndComments (cssRule);
1.42      cvs      1102:        }
                   1103:     }
                   1104:   return (cssRule);
                   1105: }
                   1106: 
                   1107: /*----------------------------------------------------------------------
1.59      cvs      1108:    ParseCSSBorderStyleTop: parse a CSS BorderStyleTop
1.42      cvs      1109:    attribute string.                                          
                   1110:   ----------------------------------------------------------------------*/
1.79      cvs      1111: static char *ParseCSSBorderStyleTop (Element element, PSchema tsch,
                   1112:                                     PresentationContext context,
                   1113:                                     char *cssRule, CSSInfoPtr css,
                   1114:                                     ThotBool isHTML)
1.42      cvs      1115: {
1.43      cvs      1116:   PresentationValue   border;
                   1117:   
1.82      cvs      1118:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      1119:   cssRule = ParseBorderStyle (cssRule, &border);
1.295     vatton   1120:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton   1121:   if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.117     vatton   1122:     {
                   1123:       /* check if it's an important rule */
                   1124:       TtaSetStylePresentation (PRBorderTopStyle, element, tsch, context, border);
                   1125:     }
1.42      cvs      1126:   return (cssRule);
                   1127: }
                   1128: 
                   1129: /*----------------------------------------------------------------------
1.59      cvs      1130:    ParseCSSBorderStyleLeft: parse a CSS BorderStyleLeft
1.42      cvs      1131:    attribute string.                                          
                   1132:   ----------------------------------------------------------------------*/
1.79      cvs      1133: static char *ParseCSSBorderStyleLeft (Element element, PSchema tsch,
                   1134:                                      PresentationContext context,
                   1135:                                      char *cssRule, CSSInfoPtr css,
                   1136:                                      ThotBool isHTML)
1.42      cvs      1137: {
1.43      cvs      1138:   PresentationValue   border;
                   1139:   
1.82      cvs      1140:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      1141:   cssRule = ParseBorderStyle (cssRule, &border);
1.295     vatton   1142:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton   1143:   if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.117     vatton   1144:     {
                   1145:       /* check if it's an important rule */
                   1146:       TtaSetStylePresentation (PRBorderLeftStyle, element, tsch, context, border);
                   1147:     }
1.42      cvs      1148:   return (cssRule);
                   1149: }
                   1150: 
                   1151: /*----------------------------------------------------------------------
1.59      cvs      1152:    ParseCSSBorderStyleBottom: parse a CSS BorderStyleBottom
1.1       cvs      1153:    attribute string.                                          
                   1154:   ----------------------------------------------------------------------*/
1.79      cvs      1155: static char *ParseCSSBorderStyleBottom (Element element, PSchema tsch,
                   1156:                                        PresentationContext context,
                   1157:                                        char *cssRule, CSSInfoPtr css,
                   1158:                                        ThotBool isHTML)
1.1       cvs      1159: {
1.43      cvs      1160:   PresentationValue   border;
                   1161:   
1.82      cvs      1162:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      1163:   cssRule = ParseBorderStyle (cssRule, &border);
1.295     vatton   1164:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton   1165:   if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.117     vatton   1166:     {
                   1167:       /* check if it's an important rule */
                   1168:       TtaSetStylePresentation (PRBorderBottomStyle, element, tsch, context, border);
                   1169:     }
1.1       cvs      1170:   return (cssRule);
                   1171: }
                   1172: 
                   1173: /*----------------------------------------------------------------------
1.59      cvs      1174:    ParseCSSBorderStyleRight: parse a CSS BorderStyleRight
1.1       cvs      1175:    attribute string.                                          
                   1176:   ----------------------------------------------------------------------*/
1.79      cvs      1177: static char *ParseCSSBorderStyleRight (Element element, PSchema tsch,
                   1178:                                       PresentationContext context,
                   1179:                                       char *cssRule, CSSInfoPtr css,
                   1180:                                       ThotBool isHTML)
1.1       cvs      1181: {
1.43      cvs      1182:   PresentationValue   border;
                   1183:   
1.82      cvs      1184:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      1185:   cssRule = ParseBorderStyle (cssRule, &border);
1.295     vatton   1186:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton   1187:   if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.117     vatton   1188:     {
                   1189:       /* check if it's an important rule */
                   1190:       TtaSetStylePresentation (PRBorderRightStyle, element, tsch, context, border);
                   1191:     }
1.1       cvs      1192:   return (cssRule);
                   1193: }
                   1194: 
                   1195: /*----------------------------------------------------------------------
1.59      cvs      1196:    ParseCSSBorderStyleStyle: parse a CSS border-style        
1.1       cvs      1197:    attribute string.                                          
                   1198:   ----------------------------------------------------------------------*/
1.79      cvs      1199: static char *ParseCSSBorderStyle (Element element, PSchema tsch,
                   1200:                                  PresentationContext context,
                   1201:                                  char *cssRule, CSSInfoPtr css,
                   1202:                                  ThotBool isHTML)
1.1       cvs      1203: {
1.79      cvs      1204:   char *ptrT, *ptrR, *ptrB, *ptrL;
1.93      vatton   1205:   int   skippedNL;
1.42      cvs      1206: 
1.82      cvs      1207:   ptrT = SkipBlanksAndComments (cssRule);
1.42      cvs      1208:   /* First parse Border-Top */
1.43      cvs      1209:   ptrR = ParseCSSBorderStyleTop (element, tsch, context, ptrT, css, isHTML);
1.82      cvs      1210:   ptrR = SkipBlanksAndComments (ptrR);
1.301     vatton   1211:   if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.42      cvs      1212:     {
1.93      vatton   1213:       skippedNL = NewLineSkipped;
1.42      cvs      1214:       cssRule = ptrR;
                   1215:       /* apply the Border-Top to all */
1.43      cvs      1216:       ptrR = ParseCSSBorderStyleRight (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   1217:       NewLineSkipped = skippedNL;
1.43      cvs      1218:       ptrR = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   1219:       NewLineSkipped = skippedNL;
1.43      cvs      1220:       ptrR = ParseCSSBorderStyleLeft (element, tsch, context, ptrT, css, isHTML);
1.42      cvs      1221:     }
                   1222:   else
                   1223:     {
                   1224:       /* parse Border-Right */
1.43      cvs      1225:       ptrB = ParseCSSBorderStyleRight (element, tsch, context, ptrR, css, isHTML);
1.82      cvs      1226:       ptrB = SkipBlanksAndComments (ptrB);
1.301     vatton   1227:       if (*ptrB == ';' || *ptrR == '}' || *ptrB == EOS || *ptrB == ',')
1.42      cvs      1228:        {
1.93      vatton   1229:          skippedNL = NewLineSkipped;
1.42      cvs      1230:          cssRule = ptrB;
                   1231:          /* apply the Border-Top to Border-Bottom */
1.43      cvs      1232:          ptrB = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   1233:          NewLineSkipped = skippedNL;
1.42      cvs      1234:          /* apply the Border-Right to Border-Left */
1.43      cvs      1235:          ptrB = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1.42      cvs      1236:        }
                   1237:       else
                   1238:        {
                   1239:          /* parse Border-Bottom */
1.43      cvs      1240:          ptrL = ParseCSSBorderStyleBottom (element, tsch, context, ptrB, css, isHTML);
1.82      cvs      1241:          ptrL = SkipBlanksAndComments (ptrL);
1.301     vatton   1242:          if (*ptrL == ';' || *ptrR == '}' || *ptrL == EOS || *ptrL == ',')
1.42      cvs      1243:            {
                   1244:              cssRule = ptrL;
                   1245:              /* apply the Border-Right to Border-Left */
1.43      cvs      1246:              ptrL = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1.42      cvs      1247:            }
                   1248:          else
                   1249:            /* parse Border-Left */
1.43      cvs      1250:            cssRule = ParseCSSBorderStyleLeft (element, tsch, context, ptrL, css, isHTML);
1.82      cvs      1251:          cssRule = SkipBlanksAndComments (cssRule);
1.42      cvs      1252:        }
                   1253:     }
                   1254:   return (cssRule);
                   1255: }
                   1256: 
                   1257: /*----------------------------------------------------------------------
1.59      cvs      1258:    ParseCSSBorderTop: parse a CSS BorderTop
1.42      cvs      1259:    attribute string.                                          
                   1260:   ----------------------------------------------------------------------*/
1.79      cvs      1261: static char *ParseCSSBorderTop (Element element, PSchema tsch,
                   1262:                                PresentationContext context, char *cssRule,
                   1263:                                CSSInfoPtr css, ThotBool isHTML)
1.42      cvs      1264: {
1.79      cvs      1265:   char           *ptr;
1.43      cvs      1266: 
1.82      cvs      1267:   cssRule = SkipBlanksAndComments (cssRule);
1.301     vatton   1268:   while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.43      cvs      1269:     {
                   1270:       ptr = cssRule;
                   1271:       cssRule = ParseCSSBorderStyleTop (element, tsch, context, cssRule, css, isHTML);
                   1272:       if (ptr == cssRule)
                   1273:        cssRule = ParseCSSBorderTopWidth (element, tsch, context, cssRule, css, isHTML);
                   1274:       if (ptr == cssRule)
                   1275:        cssRule = ParseCSSBorderColorTop (element, tsch, context, cssRule, css, isHTML);
                   1276:       if (ptr == cssRule)
1.295     vatton   1277:        {
                   1278:          /* rule not found */
                   1279:          cssRule = SkipValue ("Invalid border value", cssRule);
                   1280:          cssRule = CheckImportantRule (cssRule, context);
                   1281:        }
1.82      cvs      1282:       cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      1283:     }
1.42      cvs      1284:   return (cssRule);
                   1285: }
                   1286: 
                   1287: /*----------------------------------------------------------------------
1.59      cvs      1288:    ParseCSSBorderLeft: parse a CSS BorderLeft
1.42      cvs      1289:    attribute string.                                          
                   1290:   ----------------------------------------------------------------------*/
1.79      cvs      1291: static char *ParseCSSBorderLeft (Element element, PSchema tsch,
                   1292:                                 PresentationContext context, char *cssRule,
                   1293:                                 CSSInfoPtr css, ThotBool isHTML)
1.42      cvs      1294: {
1.79      cvs      1295:   char           *ptr;
1.43      cvs      1296: 
1.82      cvs      1297:   cssRule = SkipBlanksAndComments (cssRule);
1.301     vatton   1298:   while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.43      cvs      1299:     {
                   1300:       ptr = cssRule;
                   1301:       cssRule = ParseCSSBorderStyleLeft (element, tsch, context, cssRule, css, isHTML);
                   1302:       if (ptr == cssRule)
                   1303:        cssRule = ParseCSSBorderLeftWidth (element, tsch, context, cssRule, css, isHTML);
                   1304:       if (ptr == cssRule)
                   1305:        cssRule = ParseCSSBorderColorLeft (element, tsch, context, cssRule, css, isHTML);
                   1306:       if (ptr == cssRule)
1.295     vatton   1307:        {
                   1308:          /* rule not found */
                   1309:          cssRule = SkipValue ("Invalid border value", cssRule);
                   1310:          cssRule = CheckImportantRule (cssRule, context);
                   1311:        }
                   1312:      cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      1313:     }
1.1       cvs      1314:   return (cssRule);
                   1315: }
                   1316: 
                   1317: /*----------------------------------------------------------------------
1.59      cvs      1318:    ParseCSSBorderBottom: parse a CSS BorderBottom
1.1       cvs      1319:    attribute string.                                          
                   1320:   ----------------------------------------------------------------------*/
1.79      cvs      1321: static char *ParseCSSBorderBottom (Element element, PSchema tsch,
                   1322:                                   PresentationContext context, char *cssRule,
                   1323:                                   CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1324: {
1.79      cvs      1325:   char           *ptr;
1.43      cvs      1326: 
1.82      cvs      1327:   cssRule = SkipBlanksAndComments (cssRule);
1.301     vatton   1328:   while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.43      cvs      1329:     {
                   1330:       ptr = cssRule;
                   1331:       cssRule = ParseCSSBorderStyleBottom (element, tsch, context, cssRule, css, isHTML);
                   1332:       if (ptr == cssRule)
                   1333:        cssRule = ParseCSSBorderBottomWidth (element, tsch, context, cssRule, css, isHTML);
                   1334:       if (ptr == cssRule)
                   1335:        cssRule = ParseCSSBorderColorBottom (element, tsch, context, cssRule, css, isHTML);
                   1336:       if (ptr == cssRule)
                   1337:        /* rule not found */
1.168     vatton   1338:        cssRule = SkipValue ("Invalid border value", cssRule);
1.82      cvs      1339:       cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      1340:     }
1.1       cvs      1341:   return (cssRule);
                   1342: }
                   1343: 
                   1344: /*----------------------------------------------------------------------
1.59      cvs      1345:    ParseCSSBorderRight: parse a CSS BorderRight
1.1       cvs      1346:    attribute string.                                          
                   1347:   ----------------------------------------------------------------------*/
1.79      cvs      1348: static char *ParseCSSBorderRight (Element element, PSchema tsch,
                   1349:                                  PresentationContext context, char *cssRule,
                   1350:                                  CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1351: {
1.79      cvs      1352:   char            *ptr;
1.43      cvs      1353: 
1.82      cvs      1354:   cssRule = SkipBlanksAndComments (cssRule);
1.301     vatton   1355:   while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.43      cvs      1356:     {
                   1357:       ptr = cssRule;
                   1358:       cssRule = ParseCSSBorderStyleRight (element, tsch, context, cssRule, css, isHTML);
                   1359:       if (ptr == cssRule)
                   1360:        cssRule = ParseCSSBorderRightWidth (element, tsch, context, cssRule, css, isHTML);
                   1361:       if (ptr == cssRule)
                   1362:        cssRule = ParseCSSBorderColorRight (element, tsch, context, cssRule, css, isHTML);
                   1363:       if (ptr == cssRule)
1.295     vatton   1364:        {
                   1365:          /* rule not found */
                   1366:          cssRule = SkipValue ("Invalid border value", cssRule);
                   1367:          cssRule = CheckImportantRule (cssRule, context);
                   1368:        }
1.82      cvs      1369:       cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      1370:     }
1.1       cvs      1371:   return (cssRule);
                   1372: }
                   1373: 
                   1374: /*----------------------------------------------------------------------
1.59      cvs      1375:    ParseCSSBorder: parse a CSS border        
1.42      cvs      1376:    attribute string.                                          
                   1377:   ----------------------------------------------------------------------*/
1.79      cvs      1378: static char *ParseCSSBorder (Element element, PSchema tsch,
                   1379:                             PresentationContext context, char *cssRule,
                   1380:                             CSSInfoPtr css, ThotBool isHTML)
1.42      cvs      1381: {
1.79      cvs      1382:   char *ptrT, *ptrR;
1.93      vatton   1383:   int   skippedNL;
1.42      cvs      1384: 
1.82      cvs      1385:   ptrT = SkipBlanksAndComments (cssRule);
1.42      cvs      1386:   /* First parse Border-Top */
                   1387:   ptrR = ParseCSSBorderTop (element, tsch, context, ptrT, css, isHTML);
1.82      cvs      1388:   ptrR = SkipBlanksAndComments (ptrR);
1.301     vatton   1389:   if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.42      cvs      1390:     {
1.93      vatton   1391:       skippedNL = NewLineSkipped;
1.42      cvs      1392:       cssRule = ptrR;
                   1393:       /* apply the Border-Top to all */
                   1394:       ptrR = ParseCSSBorderRight (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   1395:       NewLineSkipped = skippedNL;
1.42      cvs      1396:       ptrR = ParseCSSBorderBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   1397:       NewLineSkipped = skippedNL;
1.42      cvs      1398:       ptrR = ParseCSSBorderLeft (element, tsch, context, ptrT, css, isHTML);
                   1399:     }
                   1400:   return (cssRule);
                   1401: }
                   1402: 
1.218     vatton   1403: 
1.42      cvs      1404: /*----------------------------------------------------------------------
1.184     vatton   1405:    ParseCSSFloat: parse a CSS float attribute string    
                   1406:   ----------------------------------------------------------------------*/
                   1407: static char *ParseCSSFloat (Element element, PSchema tsch,
                   1408:                            PresentationContext context, char *cssRule,
                   1409:                            CSSInfoPtr css, ThotBool isHTML)
                   1410: {
1.257     vatton   1411:   DisplayMode         dispMode;
1.184     vatton   1412:   PresentationValue   pval;
1.288     vatton   1413:   char               *ptr = cssRule;
1.184     vatton   1414: 
                   1415:   pval.typed_data.value = 0;
1.187     vatton   1416:   pval.typed_data.unit = UNIT_BOX;
1.192     cvs      1417:   pval.typed_data.real = FALSE;
1.190     vatton   1418:   if (!strncasecmp (cssRule, "inherit", 7))
                   1419:     {
1.293     quint    1420:       pval.typed_data.unit = VALUE_INHERIT;
1.288     vatton   1421:       cssRule += 7;
1.190     vatton   1422:     }
1.184     vatton   1423:   if (!strncasecmp (cssRule, "none", 4))
1.288     vatton   1424:     {
                   1425:       pval.typed_data.value = FloatNone;
1.293     quint    1426:       cssRule += 4;
1.288     vatton   1427:     }
1.184     vatton   1428:   else if (!strncasecmp (cssRule, "left", 4))
1.288     vatton   1429:     {
                   1430:       pval.typed_data.value = FloatLeft;
1.293     quint    1431:       cssRule += 4;
1.288     vatton   1432:     }
1.184     vatton   1433:   else if (!strncasecmp (cssRule, "right", 5))
1.288     vatton   1434:     {
                   1435:       pval.typed_data.value = FloatRight;
1.293     quint    1436:       cssRule += 5;
1.288     vatton   1437:     }
1.184     vatton   1438: 
1.293     quint    1439:   if (pval.typed_data.value == 0 && pval.typed_data.unit != VALUE_INHERIT)
1.211     vatton   1440:     cssRule = SkipValue ("Invalid float value", cssRule);
1.184     vatton   1441:   else
                   1442:     {
1.295     vatton   1443:       cssRule = CheckImportantRule (cssRule, context);
1.184     vatton   1444:       if (DoApply)
                   1445:        {
1.257     vatton   1446:          dispMode = TtaGetDisplayMode (context->doc);
                   1447:          if (dispMode != NoComputedDisplay)
                   1448:            {
                   1449:            /* force a redisplay of the whole document */
                   1450:            TtaSetDisplayMode (context->doc, NoComputedDisplay);
                   1451: #ifdef AMAYA_DEBUG
                   1452:            /*printf ("Force NoComputedDisplay doc=%d\n", context->doc);*/
                   1453: #endif /* AMAYA_DEBUG */
                   1454:            }
1.184     vatton   1455:          TtaSetStylePresentation (PRFloat, element, tsch, context, pval);
                   1456:        }
1.288     vatton   1457:       cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid float value");
1.184     vatton   1458:     }
                   1459:   return (cssRule);
                   1460: }
                   1461: 
                   1462: /*----------------------------------------------------------------------
                   1463:    ParseCSSClear: parse a CSS clear rule 
1.1       cvs      1464:   ----------------------------------------------------------------------*/
1.79      cvs      1465: static char *ParseCSSClear (Element element, PSchema tsch,
                   1466:                            PresentationContext context, char *cssRule,
                   1467:                            CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1468: {
1.184     vatton   1469:   PresentationValue   pval;
                   1470: 
                   1471:   pval.typed_data.value = 0;
1.187     vatton   1472:   pval.typed_data.unit = UNIT_BOX;
1.193     vatton   1473:   pval.typed_data.real = FALSE;
1.190     vatton   1474:   if (!strncasecmp (cssRule, "inherit", 7))
1.293     quint    1475:     pval.typed_data.unit = VALUE_INHERIT;
1.184     vatton   1476:   if (!strncasecmp (cssRule, "none", 4))
                   1477:     pval.typed_data.value = ClearNone;
                   1478:   else if (!strncasecmp (cssRule, "left", 4))
                   1479:     pval.typed_data.value = ClearLeft;
                   1480:   else if (!strncasecmp (cssRule, "right", 5))
                   1481:     pval.typed_data.value = ClearRight;
                   1482:   else if (!strncasecmp (cssRule, "both", 4))
                   1483:     pval.typed_data.value = ClearBoth;
                   1484: 
1.293     quint    1485:   if (pval.typed_data.value == 0 && pval.typed_data.unit != VALUE_INHERIT)
1.295     vatton   1486:     {
                   1487:       cssRule = SkipValue ("Invalid clear value", cssRule);
                   1488:       cssRule = CheckImportantRule (cssRule, context);
                   1489:       cssRule = SkipValue (NULL, cssRule);
                   1490:     }
1.184     vatton   1491:   else
                   1492:     {
1.295     vatton   1493:       cssRule = SkipValue (NULL, cssRule);
                   1494:       cssRule = CheckImportantRule (cssRule, context);
1.184     vatton   1495:       if (DoApply)
1.295     vatton   1496:        TtaSetStylePresentation (PRClear, element, tsch, context, pval);
1.184     vatton   1497:     }
                   1498:   return (cssRule);
                   1499: }
                   1500: 
                   1501: /*----------------------------------------------------------------------
1.59      cvs      1502:    ParseCSSDisplay: parse a CSS display attribute string        
1.1       cvs      1503:   ----------------------------------------------------------------------*/
1.79      cvs      1504: static char *ParseCSSDisplay (Element element, PSchema tsch,
                   1505:                              PresentationContext context, char *cssRule,
                   1506:                              CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1507: {
1.184     vatton   1508:   PresentationValue   pval;
1.288     vatton   1509:   char               *ptr = cssRule;
1.1       cvs      1510: 
1.184     vatton   1511:   pval.typed_data.unit = UNIT_REL;
                   1512:   pval.typed_data.real = FALSE;
                   1513:   cssRule = SkipBlanksAndComments (cssRule);
                   1514:   if (!strncasecmp (cssRule, "none", 4))
1.288     vatton   1515:     {
                   1516:       cssRule += 4;
                   1517:       pval.typed_data.value = DisplayNone;
                   1518:     }
1.277     quint    1519:   else if (!strncasecmp (cssRule, "block", 5))
1.288     vatton   1520:     {
                   1521:       cssRule += 5;
                   1522:       pval.typed_data.value = Block;
                   1523:     }
1.303     vatton   1524:   else if (!strncasecmp (cssRule, "inline-block", 12))
                   1525:     {
                   1526:       cssRule += 12;
                   1527:       pval.typed_data.value = InlineBlock;
                   1528:     }
1.277     quint    1529:   else if (!strncasecmp (cssRule, "inline", 6))
1.288     vatton   1530:     {
                   1531:       cssRule += 6;
                   1532:       pval.typed_data.value = Inline;
                   1533:     }
1.277     quint    1534:   else if (!strncasecmp (cssRule, "list-item", 9))
1.288     vatton   1535:     {
                   1536:       cssRule += 9;
                   1537:       pval.typed_data.value = ListItem;
                   1538:     }
1.277     quint    1539:   else if (!strncasecmp (cssRule, "run-in", 6))
1.288     vatton   1540:     {
                   1541:       cssRule += 6;
                   1542:       pval.typed_data.value = RunIn;
                   1543:     }
1.293     quint    1544:   else if (!strncasecmp (cssRule, "inherit", 7))
                   1545:     {
                   1546:       cssRule += 7;
                   1547:       pval.typed_data.unit = VALUE_INHERIT;
                   1548:     }
1.277     quint    1549:   else
1.184     vatton   1550:     {
1.277     quint    1551:       if (strncasecmp (cssRule, "table-row-group", 15) &&
                   1552:          strncasecmp (cssRule, "table-column-group", 18) &&
                   1553:          strncasecmp (cssRule, "table-header-group", 5) &&
                   1554:          strncasecmp (cssRule, "table-footer-group", 6) &&
                   1555:          strncasecmp (cssRule, "table-row", 9) &&
                   1556:          strncasecmp (cssRule, "table-column", 12) &&
                   1557:          strncasecmp (cssRule, "table-cell", 10) &&
                   1558:          strncasecmp (cssRule, "table-caption", 13) &&
1.293     quint    1559:          strncasecmp (cssRule, "inline-table", 12) &&
                   1560:          strncasecmp (cssRule, "table", 5))
                   1561:        cssRule = SkipValue ("Display value not supported", cssRule);
1.281     quint    1562:       else
                   1563:        cssRule = SkipWord (cssRule);
1.277     quint    1564:       return (cssRule);
1.184     vatton   1565:     }
1.277     quint    1566: 
1.295     vatton   1567:   cssRule = CheckImportantRule (cssRule, context);
1.277     quint    1568:   if (DoApply)
1.295     vatton   1569:     TtaSetStylePresentation (PRDisplay, element, tsch, context, pval);
1.288     vatton   1570:   cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid display value");
1.1       cvs      1571:   return (cssRule);
                   1572: }
                   1573: 
                   1574: /*----------------------------------------------------------------------
1.59      cvs      1575:    ParseCSSLetterSpacing: parse a CSS letter-spacing    
1.1       cvs      1576:    attribute string.                                          
                   1577:   ----------------------------------------------------------------------*/
1.79      cvs      1578: static char *ParseCSSLetterSpacing (Element element, PSchema tsch,
                   1579:                                    PresentationContext context, char *cssRule,
                   1580:                                    CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1581: {
1.168     vatton   1582:   cssRule = SkipValue (NULL, cssRule);
1.295     vatton   1583:   cssRule = CheckImportantRule (cssRule, context);
1.1       cvs      1584:   return (cssRule);
                   1585: }
                   1586: 
                   1587: /*----------------------------------------------------------------------
1.59      cvs      1588:    ParseCSSListStyleType: parse a CSS list-style-type
1.1       cvs      1589:    attribute string.                                          
                   1590:   ----------------------------------------------------------------------*/
1.79      cvs      1591: static char *ParseCSSListStyleType (Element element, PSchema tsch,
                   1592:                                    PresentationContext context, char *cssRule,
                   1593:                                    CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1594: {
1.281     quint    1595:   PresentationValue   pval;
1.288     vatton   1596:   char               *ptr = cssRule;
1.281     quint    1597: 
                   1598:   pval.typed_data.unit = UNIT_REL;
                   1599:   pval.typed_data.real = FALSE;
                   1600:   cssRule = SkipBlanksAndComments (cssRule);
                   1601:   if (!strncasecmp (cssRule, "disc", 4))
1.288     vatton   1602:     {
                   1603:       cssRule += 4;
                   1604:       pval.typed_data.value = Disc;
                   1605:     }
1.281     quint    1606:   else if (!strncasecmp (cssRule, "circle", 6))
1.293     quint    1607:     {
1.288     vatton   1608:       cssRule += 6;
                   1609:       pval.typed_data.value = Circle;
1.293     quint    1610:     }
1.281     quint    1611:   else if (!strncasecmp (cssRule, "square", 6))
1.293     quint    1612:     {
1.288     vatton   1613:       cssRule += 6;
1.293     quint    1614:       pval.typed_data.value = Square;
                   1615:     }
1.283     quint    1616:   else if (!strncasecmp (cssRule, "decimal-leading-zero", 20))
1.293     quint    1617:     {
1.288     vatton   1618:       cssRule += 20;
1.293     quint    1619:       pval.typed_data.value = DecimalLeadingZero;
                   1620:     }
1.281     quint    1621:   else if (!strncasecmp (cssRule, "decimal", 7))
1.293     quint    1622:     {
1.288     vatton   1623:       cssRule += 7;
1.293     quint    1624:       pval.typed_data.value = Decimal;
                   1625:     }
1.281     quint    1626:   else if (!strncasecmp (cssRule, "lower-roman", 11))
1.293     quint    1627:     {
1.288     vatton   1628:       cssRule += 11;
1.293     quint    1629:       pval.typed_data.value = LowerRoman;
                   1630:     }
1.281     quint    1631:   else if (!strncasecmp (cssRule, "upper-roman", 11))
1.293     quint    1632:     {
1.288     vatton   1633:       cssRule += 11;
1.293     quint    1634:       pval.typed_data.value = UpperRoman;
                   1635:     }
1.281     quint    1636:   else if (!strncasecmp (cssRule, "lower-greek", 11))
1.293     quint    1637:     {
1.288     vatton   1638:       cssRule += 11;
1.293     quint    1639:       pval.typed_data.value = LowerGreek;
                   1640:     }
1.281     quint    1641:   else if (!strncasecmp (cssRule, "lower-latin", 11))
1.293     quint    1642:     {
1.288     vatton   1643:       cssRule += 11;
1.293     quint    1644:       pval.typed_data.value = LowerLatin;
                   1645:     }
1.281     quint    1646:   else if (!strncasecmp (cssRule, "lower-alpha", 11))
1.293     quint    1647:     {
1.288     vatton   1648:       cssRule += 11;
1.293     quint    1649:       pval.typed_data.value = LowerLatin;
                   1650:     }
1.281     quint    1651:   else if (!strncasecmp (cssRule, "upper-latin", 11))
1.293     quint    1652:     {
1.288     vatton   1653:       cssRule += 11;
1.293     quint    1654:       pval.typed_data.value = UpperLatin;
                   1655:     }
1.281     quint    1656:   else if (!strncasecmp (cssRule, "upper-alpha", 11))
1.293     quint    1657:     {
1.288     vatton   1658:       cssRule += 11;
1.293     quint    1659:       pval.typed_data.value = UpperLatin;
                   1660:     }
1.281     quint    1661:   else if (!strncasecmp (cssRule, "armenian", 8))
1.293     quint    1662:     {
1.288     vatton   1663:       cssRule += 8;
1.293     quint    1664:       pval.typed_data.value = Decimal;
                   1665:     }
1.281     quint    1666:   else if (!strncasecmp (cssRule, "georgian", 8))
1.293     quint    1667:     {
1.288     vatton   1668:       cssRule += 8;
1.293     quint    1669:       pval.typed_data.value = Decimal;
                   1670:     }
1.281     quint    1671:   else if (!strncasecmp (cssRule, "none", 4))
1.293     quint    1672:     {
1.288     vatton   1673:       cssRule += 4;
1.293     quint    1674:       pval.typed_data.value = ListStyleTypeNone;
                   1675:     }
1.281     quint    1676:   else if (!strncasecmp (cssRule, "inherit", 7))
                   1677:     {
1.293     quint    1678:       cssRule += 7;
                   1679:       pval.typed_data.unit = VALUE_INHERIT;
1.281     quint    1680:     }
                   1681:   else
                   1682:     {
                   1683:       cssRule = SkipValue ("Invalid list-style-type value", cssRule);
                   1684:       return (cssRule);
                   1685:     }
                   1686: 
1.295     vatton   1687:   cssRule = CheckImportantRule (cssRule, context);
1.281     quint    1688:   if (DoApply)
1.295     vatton   1689:     TtaSetStylePresentation (PRListStyleType, element, tsch, context, pval);
1.288     vatton   1690:   cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style-type value");
1.1       cvs      1691:   return (cssRule);
                   1692: }
                   1693: 
                   1694: /*----------------------------------------------------------------------
1.281     quint    1695:   ParseCSSUrl: parse an URL
                   1696:   ----------------------------------------------------------------------*/
                   1697: static char *ParseCSSUrl (char *cssRule, char **url)
                   1698: {
                   1699:   char                       saved;
                   1700:   char                      *base, *ptr;
                   1701: 
                   1702:   cssRule = SkipBlanksAndComments (cssRule);
                   1703:   saved = *cssRule;
                   1704:   if (*cssRule == '(')
                   1705:     {
                   1706:       cssRule++;
                   1707:       cssRule = SkipBlanksAndComments (cssRule);
                   1708:       /*** Escaped quotes are not handled. See function SkipQuotedString */
                   1709:       if (*cssRule == '"')
                   1710:        {
                   1711:          cssRule++;
                   1712:          base = cssRule;
                   1713:          while (*cssRule != EOS && *cssRule != '"')
                   1714:            cssRule++;
                   1715:        }
                   1716:       else if (*cssRule == '\'')
                   1717:        {
                   1718:          cssRule++;
                   1719:          base = cssRule;
                   1720:          while (*cssRule != EOS && *cssRule != '\'')
                   1721:            cssRule++;
                   1722:        }
                   1723:       else
                   1724:        {
                   1725:          base = cssRule;
                   1726:          while (*cssRule != EOS && *cssRule != ')')
                   1727:            cssRule++;
                   1728:        }
                   1729:       /* keep the current position */
                   1730:       ptr = cssRule;
                   1731:       if (saved == ')')
                   1732:        {
                   1733:          /* remove extra spaces */
                   1734:          if (cssRule[-1] == SPACE)
                   1735:            {
                   1736:              *cssRule = SPACE;
                   1737:              cssRule--;
                   1738:              while (cssRule[-1] == SPACE)
                   1739:                cssRule--;
                   1740:            }
                   1741:        }
                   1742:       saved = *cssRule;
                   1743:       *cssRule = EOS;
                   1744:       *url = TtaStrdup (base);
                   1745:       *cssRule = saved;
                   1746:       if (saved == '"' || saved == '\'')
                   1747:        /* we need to skip the quote character and possible spaces */
                   1748:        {
                   1749:          cssRule++;
                   1750:          cssRule = SkipBlanksAndComments (cssRule);
                   1751:        }
                   1752:       else
                   1753:        cssRule = ptr;
                   1754:     }
                   1755:   cssRule++;
                   1756:   return cssRule;
                   1757: }
                   1758: 
                   1759: /*----------------------------------------------------------------------
1.302     quint    1760:   ParseCSSImageCallback: Callback called asynchronously by
                   1761:   FetchImage when a CSS image (background-image or list-style-image)
                   1762:   has been fetched.
                   1763:   ----------------------------------------------------------------------*/
                   1764: void ParseCSSImageCallback (Document doc, Element element, char *file,
                   1765:                            void *extra, ThotBool isnew)
                   1766: {
                   1767:   DisplayMode                dispMode = DisplayImmediately;
                   1768:   CSSImageCallbackPtr        callblock;
                   1769:   Element                    el;
                   1770:   PSchema                    tsch;
                   1771:   CSSInfoPtr                 css;
                   1772:   PInfoPtr                   pInfo;
                   1773:   PresentationContext        ctxt;
                   1774:   PresentationValue          image;
                   1775:   PresentationValue          value;
                   1776:   ThotBool                   enabled;
                   1777: 
                   1778:   callblock = (CSSImageCallbackPtr) extra;
                   1779:   if (callblock == NULL)
                   1780:     return;
                   1781: 
                   1782:   css = NULL;
                   1783:   el = callblock->el;
                   1784:   tsch = callblock->tsch;
                   1785:   ctxt = callblock->ctxt;
                   1786:   if (doc == 0 && !isnew)
                   1787:     /* apply to the current document only */
                   1788:     doc = ctxt->doc;
                   1789:   if (doc)
                   1790:     {
                   1791:       /* avoid too many redisplay */
                   1792:       dispMode = TtaGetDisplayMode (doc);
                   1793:       if (dispMode == DisplayImmediately)
                   1794:        TtaSetDisplayMode (doc, DeferredDisplay);
                   1795:     }
                   1796:   else
                   1797:     {
                   1798:       /* check if the CSS still exists */
                   1799:       css = CSSList;
                   1800:       while (css && css != callblock->css)
                   1801:        css = css->NextCSS;
                   1802:       if (css == NULL)
                   1803:        tsch = NULL;
                   1804:     }
                   1805: 
                   1806:   if (el || tsch)
                   1807:     {
                   1808:       /* Ok the image was fetched */
                   1809:       image.typed_data.unit = UNIT_REL;
                   1810:       image.typed_data.real = FALSE;
                   1811:       image.pointer = file;
                   1812:       TtaSetStylePresentation (callblock->ruleType, el, tsch, ctxt, image);
                   1813:       
                   1814:       if (callblock->ruleType == PRBackgroundPicture)
                   1815:        /* enforce the showbox */
                   1816:        {
                   1817:          value.typed_data.value = 1;
                   1818:          value.typed_data.unit = UNIT_REL;
                   1819:          value.typed_data.real = FALSE;
                   1820:          TtaSetStylePresentation (PRShowBox, el, tsch, ctxt, value);
                   1821:        }
                   1822:       /* check if the context can be freed */
                   1823:       ctxt->uses -= 1;
                   1824:       if (ctxt->uses == 0)
                   1825:        /* no other image loading */
                   1826:        TtaFreeMemory (ctxt);
                   1827:     }
                   1828: 
                   1829:   TtaFreeMemory (callblock);
                   1830:   /* restore the display mode */
                   1831:   if (doc)
                   1832:     {
                   1833:       if (dispMode == DisplayImmediately)
                   1834:        TtaSetDisplayMode (doc, dispMode);
                   1835:     }
                   1836:   else if (css)
                   1837:     {
                   1838:       for (doc = 1; doc < DocumentTableLength; doc++)
                   1839:        if (css->infos[doc] &&
                   1840:            /* don't manage a document used by make book */
                   1841:            (DocumentMeta[doc] == NULL ||
                   1842:             DocumentMeta[doc]->method != CE_MAKEBOOK))
                   1843:          {
                   1844:            pInfo = css->infos[doc];
                   1845:            enabled = FALSE;
                   1846:            while (pInfo && !enabled)
                   1847:              {
                   1848:                enabled = pInfo->PiEnabled;
                   1849:                pInfo = pInfo->PiNext;
                   1850:              }
                   1851:            /* Change the Display Mode to take into account the new
                   1852:               presentation */
                   1853:            dispMode = TtaGetDisplayMode (doc);
                   1854:            if (dispMode == DisplayImmediately)
                   1855:              {
                   1856:                TtaSetDisplayMode (doc, NoComputedDisplay);
                   1857:                /* Restore the display mode */
                   1858:                TtaSetDisplayMode (doc, dispMode);
                   1859:              }
                   1860:          }
                   1861:     }
                   1862: }
                   1863: 
                   1864: /*----------------------------------------------------------------------
                   1865:   SetCSSImage fetch the image referred by a background-image or a
                   1866:   list-style-image property.
                   1867:   ----------------------------------------------------------------------*/
                   1868: static char *SetCSSImage (Element element, PSchema tsch,
                   1869:                         PresentationContext ctxt, char *cssRule,
                   1870:                         CSSInfoPtr css, unsigned int ruleType)
                   1871: {
                   1872:   CSSImageCallbackPtr        callblock;
                   1873:   Element                    el;
                   1874:   char                      *url;
1.304     cvs      1875:   PresentationValue          image;
1.302     quint    1876:   char                      *bg_image;
                   1877:   char                       tempname[MAX_LENGTH];
                   1878:   char                       imgname[MAX_LENGTH];
                   1879: 
                   1880:   if (element)
                   1881:     el = element;
                   1882:   else
                   1883:     /* default element for FetchImage */
                   1884:     el = TtaGetMainRoot (ctxt->doc);
                   1885:   url = NULL;
                   1886:   cssRule = ParseCSSUrl (cssRule, &url);
                   1887:   cssRule = CheckImportantRule (cssRule, ctxt);
                   1888:   if (ctxt->destroy)
                   1889:     {
                   1890:       /* remove the background image PRule */
                   1891:       image.pointer = NULL;
                   1892:       TtaSetStylePresentation (ruleType, element, tsch, ctxt,image);
                   1893:     }
                   1894:   else if (url)
                   1895:     {
                   1896:       bg_image = TtaGetEnvString ("ENABLE_BG_IMAGES");
                   1897:       if (bg_image == NULL || !strcasecmp (bg_image, "yes"))
                   1898:        /* background images are enabled */
                   1899:        {
                   1900:          callblock = (CSSImageCallbackPtr) TtaGetMemory (sizeof (CSSImageCallbackBlock));
                   1901:          if (callblock)
                   1902:            {
                   1903:              callblock->el = element;
                   1904:              callblock->tsch = tsch;
                   1905:              callblock->css = css;
                   1906:              callblock->ctxt = ctxt;
                   1907:              callblock->ruleType = ruleType;
                   1908:              /* new use of the context */
                   1909:              ctxt->uses += 1;
                   1910:              /* check if the image url is related to an external CSS */
                   1911:              if (css)
                   1912:                {
                   1913:                  if (css->url)
                   1914:                    /* the image concerns a CSS file */
                   1915:                    NormalizeURL (url, 0, tempname, imgname, css->url);
                   1916:                  else
                   1917:                    /* the image concerns a style element */
                   1918:                    NormalizeURL (url, ctxt->doc, tempname, imgname, NULL);
                   1919:                  /* fetch and display background image of element */
                   1920:                  FetchImage (0, el, tempname, AMAYA_LOAD_IMAGE,
                   1921:                              ParseCSSImageCallback, callblock);
                   1922:                }
                   1923:              else
                   1924:                FetchImage (ctxt->doc, el, url, AMAYA_LOAD_IMAGE,
                   1925:                            ParseCSSImageCallback, callblock);
                   1926:            }
                   1927:        }
                   1928:     }
                   1929:   if (url)
                   1930:     TtaFreeMemory (url);
                   1931:   return (cssRule);
                   1932: }
                   1933: 
                   1934: /*----------------------------------------------------------------------
1.59      cvs      1935:    ParseCSSListStyleImage: parse a CSS list-style-image
1.1       cvs      1936:    attribute string.                                          
                   1937:   ----------------------------------------------------------------------*/
1.79      cvs      1938: static char *ParseCSSListStyleImage (Element element, PSchema tsch,
1.281     quint    1939:                                     PresentationContext ctxt,
                   1940:                                     char *cssRule, CSSInfoPtr css,
                   1941:                                     ThotBool isHTML)
1.1       cvs      1942: {
1.288     vatton   1943:   char               *url;
                   1944:   char               *ptr = cssRule;
1.293     quint    1945:   PresentationValue   pval;
1.281     quint    1946: 
1.293     quint    1947:   pval.typed_data.unit = UNIT_REL;
                   1948:   pval.typed_data.real = FALSE;
1.281     quint    1949:   url = NULL;
                   1950:   cssRule = SkipBlanksAndComments (cssRule);
                   1951:   if (!strncasecmp (cssRule, "none", 4))
                   1952:     {
                   1953:       cssRule += 4;
                   1954:       cssRule = CheckImportantRule (cssRule, ctxt);
1.302     quint    1955:       pval.typed_data.value = 0;
                   1956:       if (DoApply)
                   1957:        TtaSetStylePresentation (PRListStyleImage, element, tsch, ctxt, pval);
1.281     quint    1958:     }
                   1959:   else if (!strncasecmp (cssRule, "url", 3))
                   1960:     {  
                   1961:       cssRule += 3;
1.302     quint    1962:       cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
                   1963:                             PRListStyleImage);
1.281     quint    1964:     }
                   1965:   else if (!strncasecmp (cssRule, "inherit", 7))
1.288     vatton   1966:     {
                   1967:       cssRule += 7;
1.293     quint    1968:       pval.typed_data.unit = VALUE_INHERIT;
1.295     vatton   1969:       cssRule = CheckImportantRule (cssRule, ctxt);
1.293     quint    1970:       if (DoApply)
1.295     vatton   1971:        TtaSetStylePresentation (PRListStyleImage, element, tsch, ctxt, pval);
1.288     vatton   1972:       cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style-image value");
                   1973:      }
1.281     quint    1974:   else
1.295     vatton   1975:     {
                   1976:       cssRule = SkipValue ("Invalid list-style-image value", cssRule);
                   1977:       cssRule = CheckImportantRule (cssRule, ctxt);
                   1978:     }
1.1       cvs      1979:   return (cssRule);
                   1980: }
                   1981: 
                   1982: /*----------------------------------------------------------------------
1.59      cvs      1983:    ParseCSSListStylePosition: parse a CSS list-style-position
1.1       cvs      1984:    attribute string.                                          
                   1985:   ----------------------------------------------------------------------*/
1.79      cvs      1986: static char *ParseCSSListStylePosition (Element element, PSchema tsch,
                   1987:                                        PresentationContext context,
                   1988:                                        char *cssRule, CSSInfoPtr css,
                   1989:                                        ThotBool isHTML)
1.1       cvs      1990: {
1.281     quint    1991:   PresentationValue   pval;
1.288     vatton   1992:   char               *ptr = cssRule;
1.281     quint    1993: 
                   1994:   pval.typed_data.unit = UNIT_REL;
                   1995:   pval.typed_data.real = FALSE;
                   1996:   cssRule = SkipBlanksAndComments (cssRule);
                   1997:   if (!strncasecmp (cssRule, "inside", 6))
1.288     vatton   1998:     {
                   1999:       pval.typed_data.value = Inside;
                   2000:       cssRule += 6;
                   2001:     }
1.281     quint    2002:   else if (!strncasecmp (cssRule, "outside", 7))
1.288     vatton   2003:     {
                   2004:       pval.typed_data.value = Outside;
                   2005:       cssRule += 7;
                   2006:     }
1.293     quint    2007:   else if (!strncasecmp (cssRule, "inherit", 7))
                   2008:     {
                   2009:       pval.typed_data.unit = VALUE_INHERIT;
                   2010:       cssRule += 7;
                   2011:     }
1.281     quint    2012:   else
                   2013:     {
1.293     quint    2014:       cssRule = SkipValue ("Invalid list-style-position value", cssRule);
1.295     vatton   2015:       cssRule = CheckImportantRule (cssRule, context);
1.281     quint    2016:       return (cssRule);
                   2017:     }
1.293     quint    2018: 
1.295     vatton   2019:   cssRule = CheckImportantRule (cssRule, context);
1.281     quint    2020:   if (DoApply)
1.295     vatton   2021:     TtaSetStylePresentation (PRListStylePosition, element, tsch, context, pval);
1.288     vatton   2022:   cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style-position value");
                   2023:  return (cssRule);
1.1       cvs      2024: }
                   2025: 
                   2026: /*----------------------------------------------------------------------
1.281     quint    2027:    ParseCSSListStyle: parse a CSS list-style value string.                                          
1.1       cvs      2028:   ----------------------------------------------------------------------*/
1.79      cvs      2029: static char *ParseCSSListStyle (Element element, PSchema tsch,
1.281     quint    2030:                                PresentationContext ctxt, char *cssRule,
1.79      cvs      2031:                                CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      2032: {
1.281     quint    2033:   int   skippedNL;
                   2034: 
                   2035:   cssRule = SkipBlanksAndComments (cssRule);
1.301     vatton   2036:   while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.281     quint    2037:     {
1.282     cvs      2038:          skippedNL = NewLineSkipped;
1.281     quint    2039:       /* perhaps a list-style-image */
                   2040:       if (!strncasecmp (cssRule, "url", 3))
                   2041:        cssRule = ParseCSSListStyleImage (element, tsch, ctxt, cssRule, css,
                   2042:                                          isHTML);
                   2043:       /* perhaps a list-style-position */
                   2044:       else if (!strncasecmp (cssRule, "inside", 6) ||
                   2045:                !strncasecmp (cssRule, "outside", 7))
                   2046:        cssRule = ParseCSSListStylePosition (element, tsch, ctxt, cssRule,
                   2047:                                             css, isHTML);
                   2048:       /* perhaps a list-style-type */
                   2049:       else if (!strncasecmp (cssRule, "disc", 4) ||
                   2050:               !strncasecmp (cssRule, "circle", 6) ||
                   2051:               !strncasecmp (cssRule, "square", 6) ||
                   2052:               !strncasecmp (cssRule, "decimal", 7) ||
                   2053:               !strncasecmp (cssRule, "decimal-leading-zero", 20) ||
                   2054:               !strncasecmp (cssRule, "lower-roman", 11) ||
                   2055:               !strncasecmp (cssRule, "upper-roman", 11) ||
                   2056:               !strncasecmp (cssRule, "lower-greek", 11) ||
                   2057:               !strncasecmp (cssRule, "lower-latin", 11) ||
                   2058:               !strncasecmp (cssRule, "lower-alpha", 11) ||
                   2059:               !strncasecmp (cssRule, "upper-latin", 11) ||
                   2060:               !strncasecmp (cssRule, "upper-alpha", 11) ||
                   2061:               !strncasecmp (cssRule, "armenian", 8) ||
                   2062:               !strncasecmp (cssRule, "georgian", 8) ||
                   2063:               !strncasecmp (cssRule, "none", 4) ||
                   2064:               !strncasecmp (cssRule, "inherit", 7))
                   2065:        cssRule = ParseCSSListStyleType (element, tsch, ctxt, cssRule, css,
                   2066:                                         isHTML);
                   2067:       else
                   2068:        {
                   2069:          NewLineSkipped = skippedNL;
                   2070:          /* rule not found */
                   2071:          cssRule = SkipProperty (cssRule, FALSE);
                   2072:        }
                   2073:       cssRule = SkipBlanksAndComments (cssRule);
                   2074:     }
1.1       cvs      2075:   return (cssRule);
                   2076: }
                   2077: 
                   2078: /*----------------------------------------------------------------------
1.59      cvs      2079:    ParseCSSTextAlign: parse a CSS text-align            
1.1       cvs      2080:    attribute string.                                          
                   2081:   ----------------------------------------------------------------------*/
1.79      cvs      2082: static char *ParseCSSTextAlign (Element element, PSchema tsch,
                   2083:                                PresentationContext context, char *cssRule,
                   2084:                                CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      2085: {
1.288     vatton   2086:    char *ptr = cssRule;
1.1       cvs      2087:    PresentationValue   align;
                   2088: 
                   2089:    align.typed_data.value = 0;
1.184     vatton   2090:    align.typed_data.unit = UNIT_REL;
1.1       cvs      2091:    align.typed_data.real = FALSE;
                   2092: 
1.82      cvs      2093:    cssRule = SkipBlanksAndComments (cssRule);
                   2094:    if (!strncasecmp (cssRule, "left", 4))
1.1       cvs      2095:      {
                   2096:        align.typed_data.value = AdjustLeft;
1.288     vatton   2097:        cssRule += 4;
1.1       cvs      2098:      }
1.82      cvs      2099:    else if (!strncasecmp (cssRule, "right", 5))
1.1       cvs      2100:      {
                   2101:        align.typed_data.value = AdjustRight;
1.288     vatton   2102:        cssRule += 5;
1.1       cvs      2103:      }
1.82      cvs      2104:    else if (!strncasecmp (cssRule, "center", 6))
1.1       cvs      2105:      {
                   2106:        align.typed_data.value = Centered;
1.288     vatton   2107:        cssRule += 6;
1.1       cvs      2108:      }
1.82      cvs      2109:    else if (!strncasecmp (cssRule, "justify", 7))
1.1       cvs      2110:      {
1.81      cvs      2111:        align.typed_data.value = Justify;
1.288     vatton   2112:        cssRule += 7;
1.1       cvs      2113:      }
                   2114:    else
                   2115:      {
1.211     vatton   2116:        cssRule = SkipValue ("Invalid text-align value", cssRule);
1.295     vatton   2117:        cssRule = CheckImportantRule (cssRule, context);
1.211     vatton   2118:        return (cssRule);
1.1       cvs      2119:      }
                   2120: 
                   2121:    /*
                   2122:     * install the new presentation.
                   2123:     */
1.295     vatton   2124:    cssRule = CheckImportantRule (cssRule, context);
1.116     vatton   2125:    if (align.typed_data.value && DoApply)
1.295     vatton   2126:      TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
1.288     vatton   2127:    cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid text-align value");
1.1       cvs      2128:    return (cssRule);
                   2129: }
                   2130: 
                   2131: /*----------------------------------------------------------------------
1.243     quint    2132:   ParseCSSTextAnchor: parse a CSS text-anchor property (SVG property)
                   2133:   We use the Thot Adjust PRule to represent the text-anchor property
                   2134:   for CSS 1.0, as Adjust is not used otherwise in this context.
                   2135:   ----------------------------------------------------------------------*/
                   2136: static char *ParseCSSTextAnchor (Element element, PSchema tsch,
                   2137:                                 PresentationContext context, char *cssRule,
                   2138:                                 CSSInfoPtr css, ThotBool isHTML)
                   2139: {
                   2140:    PresentationValue   align;
1.288     vatton   2141:    char               *ptr = cssRule;
1.243     quint    2142: 
                   2143:    align.typed_data.value = 0;
                   2144:    align.typed_data.unit = UNIT_REL;
                   2145:    align.typed_data.real = FALSE;
                   2146: 
                   2147:    cssRule = SkipBlanksAndComments (cssRule);
                   2148:    if (!strncasecmp (cssRule, "start", 5))
                   2149:      {
                   2150:        align.typed_data.value = AdjustLeft;
1.288     vatton   2151:        cssRule += 5;
1.243     quint    2152:      }
                   2153:    else if (!strncasecmp (cssRule, "middle", 6))
                   2154:      {
                   2155:        align.typed_data.value = Centered;
1.288     vatton   2156:        cssRule += 6;
1.243     quint    2157:      }
                   2158:    else if (!strncasecmp (cssRule, "end", 3))
                   2159:      {
                   2160:        align.typed_data.value = AdjustRight;
1.288     vatton   2161:        cssRule += 3;
1.243     quint    2162:      }
                   2163:    else if (!strncasecmp (cssRule, "inherit", 7))
                   2164:      {
1.293     quint    2165:        align.typed_data.unit = VALUE_INHERIT;
1.288     vatton   2166:        cssRule += 7;
1.243     quint    2167:      }
                   2168:    else
                   2169:      {
                   2170:        cssRule = SkipValue ("Invalid text-anchor value", cssRule);
1.295     vatton   2171:        cssRule = CheckImportantRule (cssRule, context);
                   2172:       return (cssRule);
1.243     quint    2173:      }
                   2174: 
                   2175:    /*
                   2176:     * install the new presentation.
                   2177:     */
1.295     vatton   2178:    cssRule = CheckImportantRule (cssRule, context);
1.293     quint    2179:    if (DoApply &&
                   2180:        (align.typed_data.value || align.typed_data.unit == VALUE_INHERIT))
1.295     vatton   2181:      TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
1.288     vatton   2182:    cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid text-anchor value");
1.243     quint    2183:    return (cssRule);
                   2184: }
                   2185: 
                   2186: /*----------------------------------------------------------------------
1.112     quint    2187:    ParseCSSDirection: parse a CSS direction property
                   2188:   ----------------------------------------------------------------------*/
                   2189: static char *ParseCSSDirection (Element element, PSchema tsch,
                   2190:                                PresentationContext context, char *cssRule,
                   2191:                                CSSInfoPtr css, ThotBool isHTML)
                   2192: {
                   2193:    PresentationValue   direction;
1.288     vatton   2194:    char               *ptr = cssRule;
1.112     quint    2195: 
                   2196:    direction.typed_data.value = 0;
1.184     vatton   2197:    direction.typed_data.unit = UNIT_REL;
1.112     quint    2198:    direction.typed_data.real = FALSE;
                   2199: 
                   2200:    cssRule = SkipBlanksAndComments (cssRule);
                   2201:    if (!strncasecmp (cssRule, "ltr", 3))
                   2202:      {
1.184     vatton   2203:        direction.typed_data.value = LeftToRight;
1.288     vatton   2204:        cssRule += 3;
1.112     quint    2205:      }
                   2206:    else if (!strncasecmp (cssRule, "rtl", 3))
                   2207:      {
1.184     vatton   2208:        direction.typed_data.value = RightToLeft;
1.288     vatton   2209:        cssRule += 3;
1.112     quint    2210:      }
                   2211:    else if (!strncasecmp (cssRule, "inherit", 7))
                   2212:      {
1.293     quint    2213:        direction.typed_data.unit = VALUE_INHERIT;
1.288     vatton   2214:        cssRule += 7;
1.112     quint    2215:      }
                   2216:    else
                   2217:      {
1.211     vatton   2218:        cssRule = SkipValue ("Invalid direction value", cssRule);
1.295     vatton   2219:        cssRule = CheckImportantRule (cssRule, context);
1.112     quint    2220:        return (cssRule);
                   2221:      }
                   2222: 
                   2223:    /*
                   2224:     * install the new presentation.
                   2225:     */
1.295     vatton   2226:    cssRule = CheckImportantRule (cssRule, context);
1.293     quint    2227:    if (DoApply &&
                   2228:        (direction.typed_data.value || direction.typed_data.unit == VALUE_INHERIT))
1.295     vatton   2229:      TtaSetStylePresentation (PRDirection, element, tsch, context, direction);
1.288     vatton   2230:    cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid direction value");
1.112     quint    2231:    return (cssRule);
                   2232: }
                   2233: 
                   2234: /*----------------------------------------------------------------------
1.113     quint    2235:    ParseCSSUnicodeBidi: parse a CSS unicode-bidi property
                   2236:   ----------------------------------------------------------------------*/
                   2237: static char *ParseCSSUnicodeBidi (Element element, PSchema tsch,
                   2238:                                  PresentationContext context, char *cssRule,
                   2239:                                  CSSInfoPtr css, ThotBool isHTML)
                   2240: {
                   2241:    PresentationValue   bidi;
1.288     vatton   2242:    char               *ptr = cssRule;
1.113     quint    2243: 
                   2244:    bidi.typed_data.value = 0;
1.184     vatton   2245:    bidi.typed_data.unit = UNIT_REL;
1.113     quint    2246:    bidi.typed_data.real = FALSE;
                   2247: 
                   2248:    cssRule = SkipBlanksAndComments (cssRule);
                   2249:    if (!strncasecmp (cssRule, "normal", 6))
                   2250:      {
1.184     vatton   2251:        bidi.typed_data.value = Normal;
1.288     vatton   2252:        cssRule += 6;
1.113     quint    2253:      }
                   2254:    else if (!strncasecmp (cssRule, "embed", 5))
                   2255:      {
1.184     vatton   2256:        bidi.typed_data.value = Embed;
1.288     vatton   2257:        cssRule += 5;
1.113     quint    2258:      }
1.270     vatton   2259:    else if (!strncasecmp (cssRule, "bidi-override", 13))
1.113     quint    2260:      {
1.184     vatton   2261:        bidi.typed_data.value = Override;
1.288     vatton   2262:        cssRule += 13;
1.113     quint    2263:      }
                   2264:    else if (!strncasecmp (cssRule, "inherit", 7))
                   2265:      {
1.293     quint    2266:        bidi.typed_data.unit = VALUE_INHERIT;
1.288     vatton   2267:        cssRule += 7;
1.113     quint    2268:      }
                   2269:    else
                   2270:      {
1.211     vatton   2271:        cssRule = SkipValue ("Invalid unicode-bidi value", cssRule);
1.295     vatton   2272:        cssRule = CheckImportantRule (cssRule, context);
                   2273:       return (cssRule);
1.113     quint    2274:      }
                   2275: 
                   2276:    /*
                   2277:     * install the new presentation.
                   2278:     */
1.295     vatton   2279:    cssRule = CheckImportantRule (cssRule, context);
1.293     quint    2280:    if (DoApply &&
                   2281:        (bidi.typed_data.value || bidi.typed_data.unit == VALUE_INHERIT))
1.295     vatton   2282:      TtaSetStylePresentation (PRUnicodeBidi, element, tsch, context, bidi);
1.288     vatton   2283:    cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid unicode-bidi value");
1.113     quint    2284:    return (cssRule);
                   2285: }
                   2286: 
                   2287: /*----------------------------------------------------------------------
1.168     vatton   2288:    ParseCSSTextIndent: parse a CSS text-indent
1.1       cvs      2289:    attribute string.                                          
                   2290:   ----------------------------------------------------------------------*/
1.79      cvs      2291: static char *ParseCSSTextIndent (Element element, PSchema tsch,
                   2292:                                 PresentationContext context, char *cssRule,
                   2293:                                 CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      2294: {
                   2295:    PresentationValue   pval;
1.168     vatton   2296:    char               *ptr;
1.1       cvs      2297: 
1.82      cvs      2298:    cssRule = SkipBlanksAndComments (cssRule);
1.168     vatton   2299:    ptr = cssRule;
1.1       cvs      2300:    cssRule = ParseCSSUnit (cssRule, &pval);
1.168     vatton   2301:    if (pval.typed_data.value == 0)
1.184     vatton   2302:      pval.typed_data.unit = UNIT_PX;
                   2303:    else if (pval.typed_data.unit == UNIT_INVALID ||
                   2304:        pval.typed_data.unit == UNIT_BOX)
1.168     vatton   2305:      {
                   2306:        CSSParseError ("Invalid text-indent value", ptr, cssRule);
1.295     vatton   2307:        cssRule = CheckImportantRule (cssRule, context);
1.168     vatton   2308:        return (cssRule);
                   2309:      }
1.1       cvs      2310:    /* install the attribute */
1.295     vatton   2311:    cssRule = CheckImportantRule (cssRule, context);
1.116     vatton   2312:    if (DoApply)
1.295     vatton   2313:      TtaSetStylePresentation (PRIndent, element, tsch, context, pval);
1.1       cvs      2314:    return (cssRule);
                   2315: }
                   2316: 
                   2317: /*----------------------------------------------------------------------
1.59      cvs      2318:    ParseCSSTextTransform: parse a CSS text-transform    
1.1       cvs      2319:    attribute string.                                          
                   2320:   ----------------------------------------------------------------------*/
1.79      cvs      2321: static char *ParseCSSTextTransform (Element element, PSchema tsch,
                   2322:                                    PresentationContext context, char *cssRule,
                   2323:                                    CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      2324: {
1.168     vatton   2325:   cssRule = SkipValue (NULL, cssRule);
1.295     vatton   2326:   cssRule = CheckImportantRule (cssRule, context);
1.1       cvs      2327:   return (cssRule);
                   2328: }
                   2329: 
                   2330: /*----------------------------------------------------------------------
1.59      cvs      2331:    ParseCSSVerticalAlign: parse a CSS vertical-align    
1.1       cvs      2332:    attribute string.                                          
                   2333:   ----------------------------------------------------------------------*/
1.79      cvs      2334: static char *ParseCSSVerticalAlign (Element element, PSchema tsch,
                   2335:                                    PresentationContext context, char *cssRule,
                   2336:                                    CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      2337: {
1.273     quint    2338:   char                 *ptr;
                   2339:   PresentationValue    pval;
                   2340: 
                   2341:   pval.typed_data.unit = UNIT_REL;
                   2342:   pval.typed_data.real = FALSE;
                   2343:   cssRule = SkipBlanksAndComments (cssRule);
1.288     vatton   2344:   ptr = cssRule;
1.273     quint    2345:   if (!strncasecmp (cssRule, "baseline", 8))
                   2346:     {
                   2347:       pval.typed_data.value = 0;
1.288     vatton   2348:       cssRule += 8;
1.273     quint    2349:     }
                   2350:   else if (!strncasecmp (cssRule, "sub", 3))
                   2351:     {
                   2352:       pval.typed_data.value = -3;
1.288     vatton   2353:       cssRule += 3;
1.273     quint    2354:     }
                   2355:   else if (!strncasecmp (cssRule, "super", 5))
                   2356:     {
                   2357:       pval.typed_data.value = 4;
1.288     vatton   2358:       cssRule += 5;
1.273     quint    2359:     }
                   2360:   else if (!strncasecmp (cssRule, "top", 3))
                   2361:     {
1.275     quint    2362:       pval.typed_data.unit = UNIT_INVALID;      /* Not supported yet */
1.274     vatton   2363:       pval.typed_data.value = 0;
1.288     vatton   2364:       cssRule += 3;
1.273     quint    2365:     }
                   2366:   else if (!strncasecmp (cssRule, "text-top", 8))
                   2367:     {
1.275     quint    2368:       pval.typed_data.unit = UNIT_INVALID;      /* Not supported yet */
1.274     vatton   2369:       pval.typed_data.value = 0;
1.288     vatton   2370:       cssRule += 8;
1.273     quint    2371:     }
                   2372:   else if (!strncasecmp (cssRule, "middle", 6))
                   2373:     {
1.275     quint    2374:       pval.typed_data.unit = UNIT_INVALID;      /* Not supported yet */
1.274     vatton   2375:       pval.typed_data.value = 0;
1.288     vatton   2376:       cssRule += 6;
1.273     quint    2377:     }
                   2378:   else if (!strncasecmp (cssRule, "bottom", 6))
                   2379:     {
1.275     quint    2380:       pval.typed_data.unit = UNIT_INVALID;      /* Not supported yet */
1.274     vatton   2381:       pval.typed_data.value = 0;
1.288     vatton   2382:       cssRule += 6;
1.273     quint    2383:     }
                   2384:   else if (!strncasecmp (cssRule, "text-bottom", 11))
                   2385:     {
1.275     quint    2386:       pval.typed_data.unit = UNIT_INVALID;      /* Not supported yet */
1.274     vatton   2387:       pval.typed_data.value = 0;
1.288     vatton   2388:       cssRule += 11;
1.273     quint    2389:     }
                   2390:   else if (!strncasecmp (cssRule, "inherit", 7))
                   2391:     {
1.293     quint    2392:       pval.typed_data.unit = VALUE_INHERIT;
1.274     vatton   2393:       pval.typed_data.value = 0;
1.288     vatton   2394:       cssRule +=7;
1.273     quint    2395:     }
                   2396:   else
                   2397:     {
                   2398:       /* parse <percentage> or <length> */
                   2399:       cssRule = ParseCSSUnit (cssRule, &pval);
                   2400:       if (pval.typed_data.unit == UNIT_INVALID)
                   2401:        {
                   2402:          pval.typed_data.value = 0;
                   2403:          CSSParseError ("Invalid vertical-align value", ptr, cssRule);
1.295     vatton   2404:          cssRule = CheckImportantRule (cssRule, context);
1.288     vatton   2405:          return (cssRule);
1.273     quint    2406:        }
                   2407:       else if (pval.typed_data.value == 0)
                   2408:          pval.typed_data.unit = UNIT_PX;
                   2409:       else if (pval.typed_data.unit == UNIT_BOX)
                   2410:          pval.typed_data.unit = UNIT_EM;
                   2411:       else if (pval.typed_data.unit == UNIT_PERCENT)
                   2412:        /* it's a percentage */
                   2413:        {
                   2414:          /* convert it into a relative size */
                   2415:          pval.typed_data.unit = UNIT_REL;
                   2416:          pval.typed_data.value /= 10;
                   2417:        }
                   2418:     }
1.295     vatton   2419: 
                   2420:   cssRule = CheckImportantRule (cssRule, context);
1.273     quint    2421:   if (pval.typed_data.unit != UNIT_INVALID && DoApply)
                   2422:     TtaSetStylePresentation (PRHorizRef, element, tsch, context, pval);
1.288     vatton   2423:   cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid vertical-align value");
1.1       cvs      2424:   return (cssRule);
                   2425: }
                   2426: 
                   2427: /*----------------------------------------------------------------------
1.59      cvs      2428:    ParseCSSWhiteSpace: parse a CSS white-space          
1.1       cvs      2429:    attribute string.                                          
                   2430:   ----------------------------------------------------------------------*/
1.79      cvs      2431: static char *ParseCSSWhiteSpace (Element element, PSchema tsch,
                   2432:                                 PresentationContext context, char *cssRule,
                   2433:                                 CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      2434: {
1.288     vatton   2435:   char *ptr = cssRule;
                   2436: 
1.82      cvs      2437:    cssRule = SkipBlanksAndComments (cssRule);
                   2438:    if (!strncasecmp (cssRule, "normal", 6))
1.288     vatton   2439:      cssRule += 6;
1.82      cvs      2440:    else if (!strncasecmp (cssRule, "pre", 3))
1.288     vatton   2441:      cssRule += 3;
                   2442:     else if (!strncasecmp (cssRule, "nowrap", 6))
                   2443:      cssRule += 6;
                   2444:     else if (!strncasecmp (cssRule, "pre-wrap", 8))
                   2445:      cssRule += 8;
                   2446:     else if (!strncasecmp (cssRule, "pre-line", 8))
                   2447:      cssRule += 8;
                   2448:     else if (!strncasecmp (cssRule, "inherit", 7))
                   2449:      cssRule += 7;
1.1       cvs      2450:    else
1.295     vatton   2451:      cssRule = SkipValue ("Invalid white-space value", cssRule);
                   2452: 
                   2453:    cssRule = CheckImportantRule (cssRule, context);
1.288     vatton   2454:    cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid white-space value");
1.1       cvs      2455:    return (cssRule);
                   2456: }
                   2457: 
                   2458: /*----------------------------------------------------------------------
1.59      cvs      2459:    ParseCSSWordSpacing: parse a CSS word-spacing        
1.1       cvs      2460:    attribute string.                                          
                   2461:   ----------------------------------------------------------------------*/
1.79      cvs      2462: static char *ParseCSSWordSpacing (Element element, PSchema tsch,
                   2463:                                  PresentationContext context, char *cssRule,
                   2464:                                  CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      2465: {
1.168     vatton   2466:   cssRule = SkipValue (NULL, cssRule);
1.295     vatton   2467:   cssRule = CheckImportantRule (cssRule, context);
1.1       cvs      2468:   return (cssRule);
                   2469: }
                   2470: 
                   2471: /*----------------------------------------------------------------------
1.162     quint    2472:    ParseCSSLineHeight: parse a CSS line-height property
1.25      cvs      2473:   ----------------------------------------------------------------------*/
1.162     quint    2474: static char *ParseCSSLineHeight (Element element, PSchema tsch,
1.166     vatton   2475:                                 PresentationContext context, char *cssRule,
                   2476:                                 CSSInfoPtr css, ThotBool isHTML)
1.25      cvs      2477: {
1.162     quint    2478:   PresentationValue   pval;
1.288     vatton   2479:   char               *ptr;
1.162     quint    2480: 
                   2481:   ptr = cssRule;
                   2482:   if (!strncasecmp (cssRule, "normal", 6))
                   2483:     {
1.184     vatton   2484:       pval.typed_data.unit = UNIT_REL;
1.162     quint    2485:       pval.typed_data.real = TRUE;
                   2486:       pval.typed_data.value = 1100;
1.288     vatton   2487:       cssRule += 6;
1.162     quint    2488:     }
                   2489:   else if (!strncasecmp (cssRule, "inherit", 7))
                   2490:     {
1.293     quint    2491:       pval.typed_data.unit = VALUE_INHERIT;
1.288     vatton   2492:       cssRule += 6;
1.162     quint    2493:     }
                   2494:   else
                   2495:     cssRule = ParseCSSUnit (cssRule, &pval);
1.25      cvs      2496: 
1.295     vatton   2497:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton   2498:   if (pval.typed_data.unit == UNIT_INVALID)
1.168     vatton   2499:     CSSParseError ("Invalid line-height value", ptr, cssRule);
1.162     quint    2500:   else if (DoApply)
                   2501:     {
1.166     vatton   2502:       /* install the new presentation */
1.184     vatton   2503:       if (pval.typed_data.unit == UNIT_BOX)
                   2504:        pval.typed_data.unit = UNIT_EM;
1.162     quint    2505:       TtaSetStylePresentation (PRLineSpacing, element, tsch, context, pval);
                   2506:     }
                   2507:   return (cssRule);
1.25      cvs      2508: }
                   2509: 
                   2510: /*----------------------------------------------------------------------
1.222     quint    2511:    ParseCSSFontSizeAdjust: parse a CSS fontsizeAdjust attr string  
1.1       cvs      2512:    we expect the input string describing the attribute to be     
                   2513:    xx-small, x-small, small, medium, large, x-large, xx-large      
                   2514:    or an absolute size, or an imcrement relative to the parent     
                   2515:   ----------------------------------------------------------------------*/
1.219     vatton   2516: static char *ParseCSSFontSizeAdjust (Element element, PSchema tsch,
                   2517:                                     PresentationContext context, char *cssRule,
                   2518:                                     CSSInfoPtr css, ThotBool isHTML)
                   2519: {
1.234     vatton   2520:   cssRule = SkipProperty (cssRule, FALSE);
1.222     quint    2521:   return (cssRule);
1.219     vatton   2522: }
                   2523: 
                   2524: /*----------------------------------------------------------------------
1.270     vatton   2525:    ParseACSSFontSize: parse a CSS font size attr string  
1.219     vatton   2526:    we expect the input string describing the attribute to be     
                   2527:    xx-small, x-small, small, medium, large, x-large, xx-large      
1.270     vatton   2528:    or an absolute size, or an imcrement relative to the parent.
                   2529:    The parameter check is TRUE if the rule is just checked.
1.219     vatton   2530:   ----------------------------------------------------------------------*/
1.270     vatton   2531: static char *ParseACSSFontSize (Element element, PSchema tsch,
1.79      cvs      2532:                               PresentationContext context, char *cssRule,
1.270     vatton   2533:                               CSSInfoPtr css, ThotBool isHTML, ThotBool check)
1.1       cvs      2534: {
1.171     quint    2535:    ElementType         elType;
1.1       cvs      2536:    PresentationValue   pval;
1.137     vatton   2537:    char               *ptr = NULL, *ptr1 = NULL;
1.288     vatton   2538:    ThotBool           real, linespace = FALSE;
1.1       cvs      2539: 
                   2540:    pval.typed_data.real = FALSE;
1.82      cvs      2541:    cssRule = SkipBlanksAndComments (cssRule);
1.288     vatton   2542:    /* look for a '/' within the current cssRule */
                   2543:    ptr1 = strchr (cssRule, ';');
                   2544:    ptr = strchr (cssRule, '/');
                   2545:    if (ptr && (ptr1 == NULL || ptr < ptr1))
                   2546:      {
                   2547:        /* keep the line spacing rule */
                   2548:        linespace = TRUE;
                   2549:        ptr[0] = EOS;
                   2550:       }
                   2551:    else
                   2552:      ptr = NULL;
                   2553:    ptr1 = cssRule;
1.289     vatton   2554:   /* relative size */
                   2555:    if (!strncasecmp (cssRule, "larger", 6))
                   2556:      {
                   2557:        pval.typed_data.unit = UNIT_PERCENT;
                   2558:        pval.typed_data.value = 130;
                   2559:        cssRule += 6;
                   2560:      }
                   2561:    else if (!strncasecmp (cssRule, "smaller", 7))
                   2562:      {
                   2563:        pval.typed_data.unit = UNIT_PERCENT;
                   2564:        pval.typed_data.value = 80;
                   2565:        cssRule += 7;
                   2566:      }
1.287     quint    2567:    /* absolute size */
1.289     vatton   2568:    else if (!strncasecmp (cssRule, "xx-small", 8))
1.1       cvs      2569:      {
1.284     vatton   2570:        pval.typed_data.unit = UNIT_PT;
                   2571:        pval.typed_data.value = 8;
1.288     vatton   2572:        cssRule += 8;
1.1       cvs      2573:      }
1.82      cvs      2574:    else if (!strncasecmp (cssRule, "x-small", 7))
1.1       cvs      2575:      {
1.284     vatton   2576:        pval.typed_data.unit = UNIT_PT;
                   2577:        pval.typed_data.value = 10;
1.288     vatton   2578:        cssRule += 7;
1.1       cvs      2579:      }
1.82      cvs      2580:    else if (!strncasecmp (cssRule, "small", 5))
1.1       cvs      2581:      {
1.284     vatton   2582:        pval.typed_data.unit = UNIT_PT;
                   2583:        pval.typed_data.value = 11;
1.288     vatton   2584:        cssRule += 5;
1.1       cvs      2585:      }
1.82      cvs      2586:    else if (!strncasecmp (cssRule, "medium", 6))
1.1       cvs      2587:      {
1.284     vatton   2588:        pval.typed_data.unit = UNIT_PT;
                   2589:        pval.typed_data.value = 12;
1.288     vatton   2590:        cssRule += 6;
1.1       cvs      2591:      }
1.289     vatton   2592:     else if (!strncasecmp (cssRule, "large", 5))
1.1       cvs      2593:      {
1.284     vatton   2594:        pval.typed_data.unit = UNIT_PT;
                   2595:        pval.typed_data.value = 13;
1.288     vatton   2596:        cssRule += 5;
1.1       cvs      2597:      }
1.82      cvs      2598:    else if (!strncasecmp (cssRule, "x-large", 7))
1.1       cvs      2599:      {
1.284     vatton   2600:        pval.typed_data.unit = UNIT_PT;
                   2601:        pval.typed_data.value = 14;
1.288     vatton   2602:        cssRule += 7;
1.1       cvs      2603:      }
1.82      cvs      2604:    else if (!strncasecmp (cssRule, "xx-large", 8))
1.1       cvs      2605:      {
1.284     vatton   2606:        pval.typed_data.unit = UNIT_PT;
                   2607:        pval.typed_data.value = 16;
1.288     vatton   2608:        cssRule += 8;
1.1       cvs      2609:      }
1.287     quint    2610:    else if (!strncasecmp (cssRule, "inherit", 7))
                   2611:      {
1.293     quint    2612:        pval.typed_data.unit = VALUE_INHERIT;
                   2613:        pval.typed_data.value = 0;
                   2614:        cssRule += 7;
1.287     quint    2615:      }
                   2616:    /* length or percentage */
1.171     quint    2617:    else if (!isdigit (*cssRule) && *cssRule != '.')
1.260     vatton   2618:      {
1.270     vatton   2619:        if (!check)
1.295     vatton   2620:         {
                   2621:           cssRule = SkipValue ("Invalid font-size value", cssRule);
                   2622:           cssRule = CheckImportantRule (cssRule, context);
                   2623:         }
1.260     vatton   2624:        return (cssRule);
                   2625:      }
1.1       cvs      2626:    else
1.288     vatton   2627:      {       
1.1       cvs      2628:        cssRule = ParseCSSUnit (cssRule, &pval);
1.184     vatton   2629:        if (pval.typed_data.unit == UNIT_BOX)
1.171     quint    2630:         /* no unit specified */
                   2631:         {
                   2632:           elType = TtaGetElementType(element);
                   2633:           if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG"))
                   2634:             /* we are working for an SVG element. No unit means pixels */
1.184     vatton   2635:             pval.typed_data.unit = UNIT_PX;
1.171     quint    2636:         }
1.168     vatton   2637:        if (pval.typed_data.value != 0 &&
1.184     vatton   2638:           (pval.typed_data.unit == UNIT_INVALID ||
                   2639:            pval.typed_data.unit == UNIT_BOX ||
1.168     vatton   2640:            pval.typed_data.value < 0))
                   2641:         /* not a valid value */
1.1       cvs      2642:         return (cssRule);
1.184     vatton   2643:        else if (pval.typed_data.unit == UNIT_REL && pval.typed_data.value > 0)
1.1       cvs      2644:         /* CSS relative sizes have to be higher than Thot ones */
                   2645:         pval.typed_data.value += 1;
                   2646:        else 
                   2647:         {
                   2648:           real = pval.typed_data.real;
1.184     vatton   2649:           if (pval.typed_data.unit == UNIT_EM)
1.1       cvs      2650:             {
                   2651:               if (real)
                   2652:                 {
                   2653:                   pval.typed_data.value /= 10;
1.11      cvs      2654:                   pval.typed_data.real = FALSE;
1.1       cvs      2655:                   real = FALSE;
                   2656:                 }
                   2657:               else
                   2658:                 pval.typed_data.value *= 100;
1.184     vatton   2659:               pval.typed_data.unit = UNIT_PERCENT;
1.1       cvs      2660:             }
1.184     vatton   2661:           else if (pval.typed_data.unit == UNIT_XHEIGHT)
1.146     quint    2662:             {
                   2663:               /* a font size expressed in ex is converted into a percentage.
                   2664:                  For example, "3ex" is converted into "180%", supposing
                   2665:                  that 1ex is approximately 0.6 times the height of the
                   2666:                  current font */
                   2667:               if (real)
                   2668:                 {
                   2669:                   pval.typed_data.value *= 6;
                   2670:                   pval.typed_data.value /= 100;
                   2671:                   pval.typed_data.real = FALSE;
                   2672:                   real = FALSE;
                   2673:                 }
                   2674:               else
                   2675:                 pval.typed_data.value *= 60;
1.184     vatton   2676:               pval.typed_data.unit = UNIT_PERCENT;
1.146     quint    2677:             }
1.1       cvs      2678:         }
                   2679:      }
                   2680: 
1.25      cvs      2681:    /* install the presentation style */
1.295     vatton   2682:    cssRule = CheckImportantRule (cssRule, context);
1.270     vatton   2683:    if (!check && DoApply)
1.299     vatton   2684:      TtaSetStylePresentation (PRSize, element, tsch, context, pval);
1.288     vatton   2685:     if (!check && ptr)
                   2686:      cssRule = ParseCSSLineHeight (element, tsch, context, &ptr[1], css, isHTML);
                   2687:    if (linespace)
                   2688:      *ptr = '/';
                   2689: 
1.1       cvs      2690:    return (cssRule);
                   2691: }
                   2692: 
                   2693: /*----------------------------------------------------------------------
1.270     vatton   2694:    ParseCSSFontSize: parse a CSS font size attr string  
                   2695:    we expect the input string describing the attribute to be     
                   2696:    xx-small, x-small, small, medium, large, x-large, xx-large      
                   2697:    or an absolute size, or an imcrement relative to the parent     
                   2698:   ----------------------------------------------------------------------*/
                   2699: static char *ParseCSSFontSize (Element element, PSchema tsch,
                   2700:                               PresentationContext context, char *cssRule,
                   2701:                               CSSInfoPtr css, ThotBool isHTML)
                   2702: {
1.299     vatton   2703:   char               *ptr = cssRule;
1.295     vatton   2704:   cssRule = ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, FALSE);
                   2705:   cssRule = CheckImportantRule (cssRule, context);
1.299     vatton   2706:   cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid font-size value");
1.295     vatton   2707:   return cssRule;
1.270     vatton   2708: }
                   2709: 
                   2710: /*----------------------------------------------------------------------
1.268     vatton   2711:    ParseACSSFontFamily: parse a CSS font family string   
1.1       cvs      2712:    we expect the input string describing the attribute to be     
                   2713:    a common generic font style name                                
                   2714:   ----------------------------------------------------------------------*/
1.268     vatton   2715: static char *ParseACSSFontFamily (Element element, PSchema tsch,
1.79      cvs      2716:                                 PresentationContext context, char *cssRule,
                   2717:                                 CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      2718: {
                   2719:   PresentationValue   font;
1.252     vatton   2720:   char                quoteChar, *p;
1.1       cvs      2721: 
                   2722:   font.typed_data.value = 0;
1.184     vatton   2723:   font.typed_data.unit = UNIT_REL;
1.1       cvs      2724:   font.typed_data.real = FALSE;
1.82      cvs      2725:   cssRule = SkipBlanksAndComments (cssRule);
                   2726:   if (*cssRule == '"' || *cssRule == '\'')
1.1       cvs      2727:      {
                   2728:      quoteChar = *cssRule;
                   2729:      cssRule++;
                   2730:      }
                   2731:   else
1.82      cvs      2732:      quoteChar = EOS;
1.1       cvs      2733: 
1.293     quint    2734:   if (!strncasecmp (cssRule, "inherit", 7) && quoteChar == EOS)
                   2735:     {
                   2736:       font.typed_data.unit = VALUE_INHERIT;
                   2737:       cssRule += 7;
                   2738:     }
                   2739:   else if (!strncasecmp (cssRule, "times", 5) &&
1.92      cvs      2740:       (quoteChar == EOS || quoteChar == cssRule[5]))
1.86      cvs      2741:     {
1.184     vatton   2742:       font.typed_data.value = FontTimes;
1.86      cvs      2743:       cssRule += 5;
                   2744:     }
1.92      cvs      2745:   else if (!strncasecmp (cssRule, "serif", 5) &&
                   2746:       (quoteChar == EOS || quoteChar == cssRule[5]))
1.86      cvs      2747:     {
1.184     vatton   2748:       font.typed_data.value = FontTimes;
1.86      cvs      2749:       cssRule += 5;
1.92      cvs      2750:       if (quoteChar != EOS)
                   2751:        cssRule++;
1.86      cvs      2752:     }
1.92      cvs      2753:   else if (!strncasecmp (cssRule, "helvetica", 9) &&
                   2754:       (quoteChar == EOS || quoteChar == cssRule[9]))
1.86      cvs      2755:     {
1.184     vatton   2756:      font.typed_data.value = FontHelvetica;
1.86      cvs      2757:       cssRule += 9;
1.92      cvs      2758:       if (quoteChar != EOS)
                   2759:        cssRule++;
1.86      cvs      2760:     }
1.92      cvs      2761:   else if (!strncasecmp (cssRule, "verdana", 7) &&
                   2762:       (quoteChar == EOS || quoteChar == cssRule[7]))
1.86      cvs      2763:     {
1.184     vatton   2764:       font.typed_data.value = FontHelvetica;
1.86      cvs      2765:       cssRule += 7;
1.92      cvs      2766:       if (quoteChar != EOS)
                   2767:        cssRule++;
1.86      cvs      2768:     }
1.92      cvs      2769:   else if (!strncasecmp (cssRule, "sans-serif", 10) &&
                   2770:       (quoteChar == EOS || quoteChar == cssRule[10]))
1.86      cvs      2771:     {
1.184     vatton   2772:       font.typed_data.value = FontHelvetica;
1.86      cvs      2773:       cssRule += 10;
1.92      cvs      2774:       if (quoteChar != EOS)
                   2775:        cssRule++;
1.86      cvs      2776:     }
1.268     vatton   2777:   else if (!strncasecmp (cssRule, "courier new", 11) &&
                   2778:       (quoteChar == EOS || quoteChar == cssRule[11]))
                   2779:     {
                   2780:       font.typed_data.value = FontCourier;
                   2781:       cssRule += 11;
                   2782:       if (quoteChar != EOS)
                   2783:        cssRule++;
                   2784:     }
1.92      cvs      2785:   else if (!strncasecmp (cssRule, "courier", 7) &&
                   2786:       (quoteChar == EOS || quoteChar == cssRule[7]))
1.86      cvs      2787:     {
1.184     vatton   2788:       font.typed_data.value = FontCourier;
1.86      cvs      2789:       cssRule += 7;
1.92      cvs      2790:       if (quoteChar != EOS)
                   2791:        cssRule++;
1.86      cvs      2792:     }
1.92      cvs      2793:   else if (!strncasecmp (cssRule, "monospace", 9) &&
                   2794:       (quoteChar == EOS || quoteChar == cssRule[9]))
1.86      cvs      2795:     {
1.184     vatton   2796:       font.typed_data.value = FontCourier;
1.86      cvs      2797:       cssRule += 9;
1.92      cvs      2798:       if (quoteChar != EOS)
                   2799:        cssRule++;
1.86      cvs      2800:     }
1.1       cvs      2801:   else
                   2802:     /* unknown font name.  Skip it */
                   2803:     {
1.252     vatton   2804:       p = cssRule;
1.92      cvs      2805:       if (quoteChar != EOS)
1.54      cvs      2806:          cssRule = SkipQuotedString (cssRule, quoteChar);
1.86      cvs      2807:       else
1.1       cvs      2808:          cssRule = SkipWord (cssRule);
1.252     vatton   2809:       while (p == cssRule &&
1.301     vatton   2810:             *cssRule != ','  && *cssRule != ';'  && *cssRule != '}' && *cssRule != EOS)
1.252     vatton   2811:        {
                   2812:          cssRule++;
                   2813:          p = cssRule;
                   2814:          cssRule = SkipWord (cssRule);
                   2815:        }
1.82      cvs      2816:       cssRule = SkipBlanksAndComments (cssRule);
                   2817:       if (*cssRule == ',')
1.1       cvs      2818:        {
1.239     vatton   2819:          /* recursive call to ParseCSSFontFamily */
1.86      cvs      2820:          cssRule++;
1.268     vatton   2821:          cssRule = ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
1.86      cvs      2822:          return (cssRule);
1.1       cvs      2823:        }
                   2824:     }
                   2825: 
1.239     vatton   2826:   /* skip other values */
                   2827:   cssRule = SkipBlanksAndComments (cssRule);
                   2828:   while (*cssRule == ',')
                   2829:     {
                   2830:       cssRule++;
                   2831:       cssRule = SkipValue (NULL, cssRule);
                   2832:       cssRule = SkipBlanksAndComments (cssRule);
                   2833:     }
                   2834: 
1.295     vatton   2835:   cssRule = CheckImportantRule (cssRule, context);
                   2836:   if ((font.typed_data.value != 0 || font.typed_data.unit == VALUE_INHERIT) &&
                   2837:       DoApply)
                   2838:     /* install the new presentation */
                   2839:     TtaSetStylePresentation (PRFont, element, tsch, context, font);
1.1       cvs      2840:   return (cssRule);
                   2841: }
                   2842: 
                   2843: /*----------------------------------------------------------------------
1.268     vatton   2844:    ParseCSSFontFamily: parse a CSS font family string   
                   2845:    we expect the input string describing the attribute to be     
                   2846:    a common generic font style name                                
                   2847:   ----------------------------------------------------------------------*/
                   2848: static char *ParseCSSFontFamily (Element element, PSchema tsch,
                   2849:                                 PresentationContext context, char *cssRule,
                   2850:                                 CSSInfoPtr css, ThotBool isHTML)
                   2851: {
                   2852:   cssRule = ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
                   2853:   /* skip extra values */
1.301     vatton   2854:   while (cssRule && *cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.268     vatton   2855:     cssRule++;
                   2856:   return (cssRule);
                   2857: }
                   2858: 
                   2859: /*----------------------------------------------------------------------
1.273     quint    2860:    ParseACSSFontWeight: parse a CSS font weight string   
1.1       cvs      2861:    we expect the input string describing the attribute to be     
1.20      cvs      2862:    normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.1       cvs      2863:   ----------------------------------------------------------------------*/
1.263     vatton   2864: static char *ParseACSSFontWeight (Element element, PSchema tsch,
1.79      cvs      2865:                                 PresentationContext context, char *cssRule,
                   2866:                                 CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      2867: {
1.20      cvs      2868:    PresentationValue   weight;
1.1       cvs      2869: 
                   2870:    weight.typed_data.value = 0;
1.184     vatton   2871:    weight.typed_data.unit = UNIT_REL;
1.1       cvs      2872:    weight.typed_data.real = FALSE;
1.82      cvs      2873:    cssRule = SkipBlanksAndComments (cssRule);
1.270     vatton   2874:    if (!strncasecmp (cssRule, "100", 3) && cssRule[3] != '%' &&
                   2875:        !isalpha (cssRule[3]))
1.1       cvs      2876:      {
                   2877:        weight.typed_data.value = -3;
                   2878:        cssRule = SkipWord (cssRule);
                   2879:      }
1.82      cvs      2880:    else if (!strncasecmp (cssRule, "200", 3) && !isalpha (cssRule[3]))
1.1       cvs      2881:      {
                   2882:        weight.typed_data.value = -2;
                   2883:        cssRule = SkipWord (cssRule);
                   2884:      }
1.82      cvs      2885:    else if (!strncasecmp (cssRule, "300", 3) && ! isalpha(cssRule[3]))
1.1       cvs      2886:      {
                   2887:        weight.typed_data.value = -1;
                   2888:        cssRule = SkipWord (cssRule);
                   2889:      }
1.270     vatton   2890:    else if (!strncasecmp (cssRule, "normal", 6) ||
                   2891:            (!strncasecmp (cssRule, "400", 3) && !isalpha (cssRule[3])))
1.1       cvs      2892:      {
                   2893:        weight.typed_data.value = 0;
                   2894:        cssRule = SkipWord (cssRule);
                   2895:      }
1.82      cvs      2896:    else if (!strncasecmp (cssRule, "500", 3) && !isalpha (cssRule[3]))
1.1       cvs      2897:      {
                   2898:        weight.typed_data.value = +1;
                   2899:        cssRule = SkipWord (cssRule);
                   2900:      }
1.82      cvs      2901:    else if (!strncasecmp (cssRule, "600", 3) && !isalpha (cssRule[3]))
1.1       cvs      2902:      {
                   2903:        weight.typed_data.value = +2;
                   2904:        cssRule = SkipWord (cssRule);
                   2905:      }
1.270     vatton   2906:    else if (!strncasecmp (cssRule, "bold", 4) ||
                   2907:            (!strncasecmp (cssRule, "700", 3) && !isalpha (cssRule[3])))
1.1       cvs      2908:      {
                   2909:        weight.typed_data.value = +3;
                   2910:        cssRule = SkipWord (cssRule);
                   2911:      }
1.82      cvs      2912:    else if (!strncasecmp (cssRule, "800", 3) && !isalpha (cssRule[3]))
1.1       cvs      2913:      {
                   2914:        weight.typed_data.value = +4;
                   2915:        cssRule = SkipWord (cssRule);
                   2916:      }
1.82      cvs      2917:    else if (!strncasecmp (cssRule, "900", 3) && !isalpha (cssRule[3]))
1.1       cvs      2918:      {
                   2919:        weight.typed_data.value = +5;
                   2920:        cssRule = SkipWord (cssRule);
                   2921:      }
1.293     quint    2922:    else if (!strncasecmp (cssRule, "inherit", 7))
                   2923:      {
                   2924:        weight.typed_data.unit = VALUE_INHERIT;
                   2925:        cssRule += 7;
                   2926:      }
                   2927:    else if (!strncasecmp (cssRule, "bolder", 6) ||
1.287     quint    2928:            !strncasecmp (cssRule, "lighter", 7))
1.1       cvs      2929:      {
                   2930:      /* not implemented */
                   2931:      cssRule = SkipWord (cssRule);
                   2932:      return (cssRule);
                   2933:      }
                   2934:    else
                   2935:      return (cssRule);
                   2936: 
                   2937:    /*
1.20      cvs      2938:     * Here we have to reduce since only two font weight values are supported
1.1       cvs      2939:     * by the Thot presentation API.
                   2940:     */
1.293     quint    2941:    if (weight.typed_data.unit != VALUE_INHERIT)
                   2942:      {
                   2943:        if (weight.typed_data.value > 0)
                   2944:         weight.typed_data.value = WeightBold;
                   2945:        else
                   2946:         weight.typed_data.value = WeightNormal;
                   2947:      }
1.1       cvs      2948: 
                   2949:    /* install the new presentation */
1.295     vatton   2950:    cssRule = CheckImportantRule (cssRule, context);
                   2951:    if (DoApply)
                   2952:      TtaSetStylePresentation (PRWeight, element, tsch, context, weight);
1.1       cvs      2953:    return (cssRule);
                   2954: }
                   2955: 
                   2956: /*----------------------------------------------------------------------
1.263     vatton   2957:    ParseCSSFontWeight: parse a CSS font weight string   
                   2958:    we expect the input string describing the attribute to be     
                   2959:    normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
                   2960:   ----------------------------------------------------------------------*/
                   2961: static char *ParseCSSFontWeight (Element element, PSchema tsch,
                   2962:                                 PresentationContext context, char *cssRule,
                   2963:                                 CSSInfoPtr css, ThotBool isHTML)
                   2964: {
                   2965:   char           *ptr;
                   2966:   
                   2967:   ptr = cssRule;
                   2968:   cssRule = ParseACSSFontWeight (element, tsch, context, cssRule, css, isHTML);
                   2969:   if (ptr == cssRule)
                   2970:     cssRule = SkipValue ("Invalid font-weight value", cssRule);
1.295     vatton   2971:   cssRule = CheckImportantRule (cssRule, context);
1.263     vatton   2972:   return (cssRule);
                   2973: }
                   2974: 
                   2975: /*----------------------------------------------------------------------
1.293     quint    2976:    ParseACSSFontVariant: parse a CSS font variant string     
1.1       cvs      2977:    we expect the input string describing the attribute to be     
                   2978:    normal or small-caps
                   2979:   ----------------------------------------------------------------------*/
1.263     vatton   2980: static char *ParseACSSFontVariant (Element element, PSchema tsch,
1.79      cvs      2981:                                  PresentationContext context, char *cssRule,
                   2982:                                  CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      2983: {
                   2984:    PresentationValue   style;
                   2985: 
                   2986:    style.typed_data.value = 0;
1.184     vatton   2987:    style.typed_data.unit = UNIT_REL;
1.1       cvs      2988:    style.typed_data.real = FALSE;
1.82      cvs      2989:    cssRule = SkipBlanksAndComments (cssRule);
                   2990:    if (!strncasecmp (cssRule, "small-caps", 10))
1.1       cvs      2991:      {
                   2992:        /* Not supported yet */
                   2993:        cssRule = SkipWord (cssRule);
                   2994:      }
1.82      cvs      2995:    else if (!strncasecmp (cssRule, "normal", 6))
1.1       cvs      2996:      {
                   2997:        /* Not supported yet */
                   2998:        cssRule = SkipWord (cssRule);
                   2999:      }
1.82      cvs      3000:    else if (!strncasecmp (cssRule, "inherit", 7))
1.1       cvs      3001:      {
                   3002:        /* Not supported yet */
                   3003:        cssRule = SkipWord (cssRule);
                   3004:      }
1.295     vatton   3005:   return (cssRule);
1.263     vatton   3006: }
1.1       cvs      3007: 
1.263     vatton   3008: /*----------------------------------------------------------------------
                   3009:    ParseCSSFontVariant: parse a CSS font variant string     
                   3010:    we expect the input string describing the attribute to be     
                   3011:    normal or small-caps
                   3012:   ----------------------------------------------------------------------*/
                   3013: static char *ParseCSSFontVariant (Element element, PSchema tsch,
                   3014:                                  PresentationContext context, char *cssRule,
                   3015:                                  CSSInfoPtr css, ThotBool isHTML)
                   3016: {
                   3017:   char           *ptr;
                   3018:   
                   3019:   ptr = cssRule;
                   3020:   cssRule = ParseACSSFontVariant (element, tsch, context, cssRule, css, isHTML);
                   3021:   if (ptr == cssRule)
                   3022:     cssRule = SkipValue ("Invalid font-variant value", cssRule);
1.295     vatton   3023:   cssRule = CheckImportantRule (cssRule, context);
1.263     vatton   3024:   return (cssRule);
1.1       cvs      3025: }
                   3026: 
                   3027: 
                   3028: /*----------------------------------------------------------------------
1.293     quint    3029:    ParseACSSFontStyle: parse a CSS font style string     
1.1       cvs      3030:    we expect the input string describing the attribute to be     
1.287     quint    3031:    normal, italic, oblique or inherit                         
1.1       cvs      3032:   ----------------------------------------------------------------------*/
1.263     vatton   3033: static char *ParseACSSFontStyle (Element element, PSchema tsch,
1.79      cvs      3034:                                PresentationContext context, char *cssRule,
                   3035:                                CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      3036: {
                   3037:    PresentationValue   style;
                   3038:    PresentationValue   size;
                   3039: 
                   3040:    style.typed_data.value = 0;
1.184     vatton   3041:    style.typed_data.unit = UNIT_REL;
1.1       cvs      3042:    style.typed_data.real = FALSE;
                   3043:    size.typed_data.value = 0;
1.184     vatton   3044:    size.typed_data.unit = UNIT_REL;
1.1       cvs      3045:    size.typed_data.real = FALSE;
1.82      cvs      3046:    cssRule = SkipBlanksAndComments (cssRule);
                   3047:    if (!strncasecmp (cssRule, "italic", 6))
1.1       cvs      3048:      {
1.184     vatton   3049:        style.typed_data.value = StyleItalics;
1.1       cvs      3050:        cssRule = SkipWord (cssRule);
                   3051:      }
1.82      cvs      3052:    else if (!strncasecmp (cssRule, "oblique", 7))
1.1       cvs      3053:      {
1.184     vatton   3054:        style.typed_data.value = StyleOblique;
1.1       cvs      3055:        cssRule = SkipWord (cssRule);
                   3056:      }
1.82      cvs      3057:    else if (!strncasecmp (cssRule, "normal", 6))
1.1       cvs      3058:      {
1.184     vatton   3059:        style.typed_data.value = StyleRoman;
1.1       cvs      3060:        cssRule = SkipWord (cssRule);
                   3061:      }
1.108     cvs      3062:    else if (!strncasecmp (cssRule, "inherit", 7))
                   3063:      {
1.293     quint    3064:        style.typed_data.unit = VALUE_INHERIT;
1.108     cvs      3065:        cssRule = SkipWord (cssRule);
                   3066:      }
1.1       cvs      3067:    else
1.263     vatton   3068:      /* invalid font style */
                   3069:      return (cssRule);
1.1       cvs      3070: 
                   3071:    /*
                   3072:     * install the new presentation.
                   3073:     */
1.295     vatton   3074:    cssRule = CheckImportantRule (cssRule, context);
1.293     quint    3075:    if (DoApply &&
                   3076:        (style.typed_data.value != 0 || style.typed_data.unit == VALUE_INHERIT))
1.117     vatton   3077:      {
1.276     vatton   3078:        TtaSetStylePresentation (PRStyle, element, tsch, context, style);
1.117     vatton   3079:      }
1.116     vatton   3080:    if (size.typed_data.value != 0 && DoApply)
1.1       cvs      3081:      {
                   3082:        PresentationValue   previous_size;
                   3083: 
                   3084:        if (!TtaGetStylePresentation (PRSize, element, tsch, context, &previous_size))
                   3085:          {
1.293     quint    3086:             /* !!!!!!!!!!!!!!!!!!!!!!!! Unit + relative !!!!!!!!!!!!!!!! */
1.1       cvs      3087:             size.typed_data.value += previous_size.typed_data.value;
                   3088:             TtaSetStylePresentation (PRSize, element, tsch, context, size);
                   3089:          }
                   3090:        else
                   3091:          {
                   3092:             size.typed_data.value = 10;
                   3093:             TtaSetStylePresentation (PRSize, element, tsch, context, size);
                   3094:          }
                   3095:      }
                   3096:    return (cssRule);
                   3097: }
                   3098: 
                   3099: /*----------------------------------------------------------------------
1.263     vatton   3100:    ParseCSSFontStyle: parse a CSS font style string     
                   3101:    we expect the input string describing the attribute to be     
                   3102:    italic, oblique or normal                         
                   3103:   ----------------------------------------------------------------------*/
                   3104: static char *ParseCSSFontStyle (Element element, PSchema tsch,
                   3105:                                PresentationContext context, char *cssRule,
                   3106:                                CSSInfoPtr css, ThotBool isHTML)
                   3107: {
                   3108:   char           *ptr;
                   3109:   
                   3110:   ptr = cssRule;
                   3111:   cssRule = ParseACSSFontStyle (element, tsch, context, cssRule, css, isHTML);
                   3112:   if (ptr == cssRule)
                   3113:     cssRule = SkipValue ("Invalid font-style value", cssRule);
1.295     vatton   3114:   cssRule = CheckImportantRule (cssRule, context);
1.263     vatton   3115:   return (cssRule);
                   3116: }
                   3117: 
                   3118: /*----------------------------------------------------------------------
1.59      cvs      3119:   ParseCSSFont: parse a CSS font attribute string
                   3120:   we expect the input string describing the attribute to be
                   3121:   !!!!!!                                  
1.1       cvs      3122:   ----------------------------------------------------------------------*/
1.79      cvs      3123: static char *ParseCSSFont (Element element, PSchema tsch,
                   3124:                           PresentationContext context, char *cssRule,
                   3125:                           CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      3126: {
1.270     vatton   3127:   char           *ptr, *p;
1.93      vatton   3128:   int             skippedNL;
1.272     vatton   3129:   ThotBool        variant = FALSE, style = FALSE, weight = FALSE, found; 
1.1       cvs      3130: 
1.82      cvs      3131:   cssRule = SkipBlanksAndComments (cssRule);
                   3132:   if (!strncasecmp (cssRule, "caption", 7))
1.263     vatton   3133:     cssRule += 7;
1.82      cvs      3134:   else if (!strncasecmp (cssRule, "icon", 4))
1.263     vatton   3135:     cssRule += 4;
1.82      cvs      3136:   else if (!strncasecmp (cssRule, "menu", 4))
1.263     vatton   3137:     cssRule += 4;
1.82      cvs      3138:   else if (!strncasecmp (cssRule, "message-box", 11))
1.263     vatton   3139:     cssRule += 11;
1.82      cvs      3140:   else if (!strncasecmp (cssRule, "small-caption", 13))
1.263     vatton   3141:     cssRule += 13;
1.82      cvs      3142:   else if (!strncasecmp (cssRule, "status-bar", 10))
1.263     vatton   3143:     cssRule += 10;
                   3144:   else if (!strncasecmp (cssRule, "inherit", 7))
1.293     quint    3145:     {
                   3146:       ParseACSSFontStyle (element, tsch, context, cssRule, css, isHTML);
                   3147:       ParseACSSFontVariant (element, tsch, context, cssRule, css, isHTML);
                   3148:       ParseACSSFontWeight (element, tsch, context, cssRule, css, isHTML);
                   3149:       ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, FALSE);
                   3150:       ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
                   3151:       cssRule += 7;
                   3152:     }
1.1       cvs      3153:   else
1.43      cvs      3154:     {
1.270     vatton   3155:       ptr = NULL;
                   3156:       p = cssRule;
1.301     vatton   3157:       while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && p == cssRule)
1.270     vatton   3158:        {
1.272     vatton   3159:          found = FALSE;
1.270     vatton   3160:          /* style, variant, weight can appear in any order */
                   3161:          ptr = cssRule;
                   3162:          skippedNL = NewLineSkipped;
                   3163:          cssRule = ParseACSSFontStyle (element, tsch, context, cssRule, css, isHTML);
                   3164:          if (ptr != cssRule)
                   3165:            {
                   3166:              skippedNL = NewLineSkipped;
1.272     vatton   3167:              found = TRUE;
1.270     vatton   3168:              style = TRUE;
                   3169:            }
                   3170:          else
                   3171:            NewLineSkipped = skippedNL;
                   3172:          ptr = cssRule;
                   3173:          cssRule = ParseACSSFontVariant (element, tsch, context, cssRule, css, isHTML);
                   3174:          if (ptr != cssRule)
                   3175:            {
                   3176:              skippedNL = NewLineSkipped;
1.272     vatton   3177:              found = TRUE;
1.270     vatton   3178:              variant = TRUE;
                   3179:            }
                   3180:          else
                   3181:            NewLineSkipped = skippedNL;
                   3182:          ptr = cssRule;
                   3183:          cssRule = ParseACSSFontWeight (element, tsch, context, cssRule, css, isHTML);
                   3184:          if (ptr != cssRule)
                   3185:            {
                   3186:              skippedNL = NewLineSkipped;
1.272     vatton   3187:              found = TRUE;
1.270     vatton   3188:              weight = TRUE;
                   3189:            }
                   3190:          else
                   3191:            NewLineSkipped = skippedNL;
                   3192:          cssRule = SkipBlanksAndComments (cssRule);
                   3193:          p = ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, TRUE);
                   3194:          NewLineSkipped = skippedNL;
1.272     vatton   3195:          if (!found)
                   3196:            /* break the loop when the current value was not parsed */
                   3197:            p = cssRule + 1;
1.270     vatton   3198:        }
1.263     vatton   3199:       ptr = cssRule;
1.270     vatton   3200:       /* set default variant, style, weight */
                   3201:       if (!variant)
                   3202:         ParseACSSFontVariant (element, tsch, context, "normal", css, isHTML);
                   3203:       if (!style)
                   3204:         ParseACSSFontStyle (element, tsch, context, "normal", css, isHTML);
                   3205:       if (!weight)
                   3206:         ParseACSSFontWeight (element, tsch, context, "normal", css, isHTML);
                   3207:       /* now parse the font size and the font family */
1.301     vatton   3208:       if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.270     vatton   3209:        cssRule = ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, FALSE);
1.301     vatton   3210:       if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.270     vatton   3211:        cssRule = ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
1.263     vatton   3212:       if (ptr == cssRule)
1.295     vatton   3213:        {
                   3214:          cssRule = SkipValue ("Invalid font value", cssRule);
                   3215:          cssRule = CheckImportantRule (cssRule, context);
                   3216:        }
1.43      cvs      3217:     }
1.263     vatton   3218:   cssRule = SkipBlanksAndComments (cssRule);
1.301     vatton   3219:   if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.295     vatton   3220:     {
                   3221:       cssRule = SkipValue ("Invalid font value", cssRule);
                   3222:       cssRule = CheckImportantRule (cssRule, context);
                   3223:     }
1.43      cvs      3224:   return (cssRule);
1.1       cvs      3225: }
                   3226: 
                   3227: /*----------------------------------------------------------------------
1.59      cvs      3228:   ParseCSSTextDecoration: parse a CSS text decor string   
                   3229:   we expect the input string describing the attribute to be     
1.109     cvs      3230:   underline, overline, line-through, blink or none.
1.1       cvs      3231:   ----------------------------------------------------------------------*/
1.79      cvs      3232: static char *ParseCSSTextDecoration (Element element, PSchema tsch,
                   3233:                                     PresentationContext context, char *cssRule,
                   3234:                                     CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      3235: {
                   3236:    PresentationValue   decor;
1.288     vatton   3237:    char               *ptr = cssRule;
1.1       cvs      3238: 
                   3239:    decor.typed_data.value = 0;
1.184     vatton   3240:    decor.typed_data.unit = UNIT_REL;
1.1       cvs      3241:    decor.typed_data.real = FALSE;
1.82      cvs      3242:    cssRule = SkipBlanksAndComments (cssRule);
1.211     vatton   3243:    if (!strncasecmp (cssRule, "none", 4))
1.142     quint    3244:      {
                   3245:        decor.typed_data.value = NoUnderline;
1.288     vatton   3246:        cssRule += 4;
1.142     quint    3247:      }
1.211     vatton   3248:    else if (!strncasecmp (cssRule, "underline", 9))
1.1       cvs      3249:      {
                   3250:        decor.typed_data.value = Underline;
1.288     vatton   3251:        cssRule += 9;
1.1       cvs      3252:      }
1.211     vatton   3253:    else if (!strncasecmp (cssRule, "overline", 8))
1.1       cvs      3254:      {
                   3255:        decor.typed_data.value = Overline;
1.288     vatton   3256:        cssRule += 8;
1.1       cvs      3257:      }
1.211     vatton   3258:    else if (!strncasecmp (cssRule, "line-through", 12))
1.1       cvs      3259:      {
                   3260:        decor.typed_data.value = CrossOut;
1.288     vatton   3261:        cssRule += 12;
1.1       cvs      3262:      }
1.211     vatton   3263:    else if (!strncasecmp (cssRule, "blink", 5))
1.1       cvs      3264:      {
1.293     quint    3265:        /* the blink text-decoration attribute is not supported */
                   3266:        cssRule += 5;
1.1       cvs      3267:      }
1.142     quint    3268:    else if (!strncasecmp (cssRule, "inherit", 7))
1.1       cvs      3269:      {
1.293     quint    3270:        decor.typed_data.unit = VALUE_INHERIT;
1.288     vatton   3271:        cssRule += 7;
1.1       cvs      3272:      }
                   3273:    else
                   3274:      {
1.211     vatton   3275:        cssRule = SkipValue ("Invalid text-decoration value", cssRule);
1.295     vatton   3276:        cssRule = CheckImportantRule (cssRule, context);
1.211     vatton   3277:        return (cssRule);
1.1       cvs      3278:      }
                   3279: 
                   3280:    /*
                   3281:     * install the new presentation.
                   3282:     */
1.295     vatton   3283:    cssRule = CheckImportantRule (cssRule, context);
1.293     quint    3284:    if (DoApply &&
                   3285:        (decor.typed_data.value || decor.typed_data.unit == VALUE_INHERIT))
1.1       cvs      3286:        TtaSetStylePresentation (PRUnderline, element, tsch, context, decor);
1.288     vatton   3287:    cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid text-decoration value");
1.1       cvs      3288:    return (cssRule);
                   3289: }
                   3290: 
                   3291: /*----------------------------------------------------------------------
1.59      cvs      3292:    ParseCSSHeight: parse a CSS height attribute
1.1       cvs      3293:   ----------------------------------------------------------------------*/
1.79      cvs      3294: static char *ParseCSSHeight (Element element, PSchema tsch,
1.93      vatton   3295:                             PresentationContext context, char *cssRule,
                   3296:                             CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      3297: {
1.117     vatton   3298:   PresentationValue   val;
1.168     vatton   3299:   char               *ptr;
1.93      vatton   3300: 
1.117     vatton   3301:   cssRule = SkipBlanksAndComments (cssRule);
1.168     vatton   3302:   ptr = cssRule;
1.117     vatton   3303:   /* first parse the attribute string */
1.164     quint    3304:   if (!strncasecmp (cssRule, "auto", 4))
                   3305:     {
1.184     vatton   3306:       val.typed_data.unit = VALUE_AUTO;
1.164     quint    3307:       val.typed_data.value = 0;
                   3308:       val.typed_data.real = FALSE;
1.288     vatton   3309:       cssRule += 4;
1.295     vatton   3310:       cssRule = CheckImportantRule (cssRule, context);
                   3311:       cssRule = CheckImportantRule (cssRule, context);
1.288     vatton   3312:       cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid height value");
1.164     quint    3313:     }
1.117     vatton   3314:   else
1.168     vatton   3315:     cssRule = ParseCSSUnit (cssRule, &val);
1.295     vatton   3316: 
1.168     vatton   3317:   if (val.typed_data.value != 0 &&
1.184     vatton   3318:       (val.typed_data.unit == UNIT_INVALID ||
                   3319:        val.typed_data.unit == UNIT_BOX))
1.211     vatton   3320:     {
                   3321:       CSSParseError ("height value", ptr, cssRule);
1.212     cvs      3322:       val.typed_data.unit = UNIT_PX;
1.211     vatton   3323:     }
1.295     vatton   3324:   cssRule = CheckImportantRule (cssRule, context);
1.211     vatton   3325:   if (DoApply)
1.295     vatton   3326:     /* install the new presentation */
                   3327:     TtaSetStylePresentation (PRHeight, element, tsch, context, val);
1.117     vatton   3328:   return (cssRule);
1.1       cvs      3329: }
                   3330: 
                   3331: /*----------------------------------------------------------------------
1.59      cvs      3332:    ParseCSSWidth: parse a CSS width attribute
1.1       cvs      3333:   ----------------------------------------------------------------------*/
1.79      cvs      3334: static char *ParseCSSWidth (Element element, PSchema tsch,
1.78      cvs      3335:                              PresentationContext context,
1.79      cvs      3336:                              char *cssRule, CSSInfoPtr css,
1.78      cvs      3337:                              ThotBool isHTML)
1.1       cvs      3338: {
1.117     vatton   3339:   PresentationValue   val;
1.168     vatton   3340:   char               *ptr;
1.93      vatton   3341: 
1.117     vatton   3342:   cssRule = SkipBlanksAndComments (cssRule);
1.168     vatton   3343:   ptr = cssRule;
1.117     vatton   3344:   /* first parse the attribute string */
1.164     quint    3345:   if (!strncasecmp (cssRule, "auto", 4))
                   3346:     {
1.184     vatton   3347:       val.typed_data.unit = VALUE_AUTO;
1.164     quint    3348:       val.typed_data.value = 0;
                   3349:       val.typed_data.real = FALSE;
1.288     vatton   3350:       cssRule += 4;
1.295     vatton   3351:       cssRule = CheckImportantRule (cssRule, context);
1.288     vatton   3352:       cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid width value");
1.164     quint    3353:     }
1.117     vatton   3354:   else
1.164     quint    3355:       cssRule = ParseCSSUnit (cssRule, &val);
1.168     vatton   3356:   if (val.typed_data.value != 0 &&
1.184     vatton   3357:       (val.typed_data.unit == UNIT_INVALID ||
                   3358:        val.typed_data.unit == UNIT_BOX))
1.211     vatton   3359:     {
                   3360:       CSSParseError ("Invalid width value", ptr, cssRule);
1.295     vatton   3361:       cssRule = CheckImportantRule (cssRule, context);
1.212     cvs      3362:       val.typed_data.unit = UNIT_PX;
1.211     vatton   3363:     }
1.295     vatton   3364: 
                   3365:   cssRule = CheckImportantRule (cssRule, context);
1.211     vatton   3366:   if (DoApply)
1.295     vatton   3367:     /* install the new presentation */
                   3368:     TtaSetStylePresentation (PRWidth, element, tsch, context, val);
1.117     vatton   3369:   return (cssRule);
1.1       cvs      3370: }
                   3371: 
                   3372: /*----------------------------------------------------------------------
1.296     vatton   3373:    ParseACSSMarginTop: parse a CSS margin-top attribute
1.1       cvs      3374:   ----------------------------------------------------------------------*/
1.296     vatton   3375: static char *ParseACSSMarginTop (Element element, PSchema tsch,
1.78      cvs      3376:                                  PresentationContext context,
1.79      cvs      3377:                                  char *cssRule, CSSInfoPtr css,
1.78      cvs      3378:                                  ThotBool isHTML)
1.1       cvs      3379: {
                   3380:   PresentationValue   margin;
1.168     vatton   3381:   char               *ptr;
1.1       cvs      3382:   
1.82      cvs      3383:   cssRule = SkipBlanksAndComments (cssRule);
1.168     vatton   3384:   ptr = cssRule;
1.1       cvs      3385:   /* first parse the attribute string */
1.164     quint    3386:   if (!strncasecmp (cssRule, "auto", 4))
                   3387:     {
1.184     vatton   3388:       margin.typed_data.unit = VALUE_AUTO;
1.164     quint    3389:       margin.typed_data.value = 0;
                   3390:       margin.typed_data.real = FALSE;
1.288     vatton   3391:       cssRule += 4;
1.295     vatton   3392:       cssRule = CheckImportantRule (cssRule, context);
1.164     quint    3393:     }
                   3394:   else
1.168     vatton   3395:     cssRule = ParseCSSUnit (cssRule, &margin);
1.295     vatton   3396: 
                   3397:   cssRule = CheckImportantRule (cssRule, context);
1.168     vatton   3398:   if (margin.typed_data.value != 0 &&
1.184     vatton   3399:       (margin.typed_data.unit == UNIT_INVALID ||
                   3400:        margin.typed_data.unit == UNIT_BOX))
1.169     vatton   3401:     CSSParseError ("Invalid margin-top value", ptr, cssRule);
1.168     vatton   3402:   else if (DoApply)
1.295     vatton   3403:     TtaSetStylePresentation (PRMarginTop, element, tsch, context, margin);
1.1       cvs      3404:   return (cssRule);
                   3405: }
                   3406: 
                   3407: /*----------------------------------------------------------------------
1.296     vatton   3408:    ParseCSSMarginTop: parse a CSS margin-top attribute
                   3409:   ----------------------------------------------------------------------*/
                   3410: static char *ParseCSSMarginTop (Element element, PSchema tsch,
                   3411:                                  PresentationContext context,
                   3412:                                  char *cssRule, CSSInfoPtr css,
                   3413:                                  ThotBool isHTML)
                   3414: {
                   3415:   char *ptr = cssRule;
                   3416: 
                   3417:   cssRule = ParseACSSMarginTop (element, tsch, context, ptr, css, isHTML);
                   3418:   cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-top value");
                   3419:   return (cssRule);
                   3420: }
                   3421: 
                   3422: /*----------------------------------------------------------------------
                   3423:   ParseACSSMarginBottom: parse a CSS margin-bottom attribute
1.1       cvs      3424:   ----------------------------------------------------------------------*/
1.296     vatton   3425: static char *ParseACSSMarginBottom (Element element, PSchema tsch,
1.78      cvs      3426:                                     PresentationContext context,
1.79      cvs      3427:                                     char *cssRule, CSSInfoPtr css,
1.78      cvs      3428:                                     ThotBool isHTML)
1.1       cvs      3429: {
                   3430:   PresentationValue   margin;
1.168     vatton   3431:   char               *ptr;
1.1       cvs      3432:   
1.82      cvs      3433:   cssRule = SkipBlanksAndComments (cssRule);
1.168     vatton   3434:   ptr = cssRule;
1.1       cvs      3435:   /* first parse the attribute string */
1.164     quint    3436:   if (!strncasecmp (cssRule, "auto", 4))
                   3437:     {
1.184     vatton   3438:       margin.typed_data.unit = VALUE_AUTO;
1.164     quint    3439:       margin.typed_data.value = 0;
                   3440:       margin.typed_data.real = FALSE;
1.288     vatton   3441:       cssRule += 4;
1.295     vatton   3442:       cssRule = CheckImportantRule (cssRule, context);
1.164     quint    3443:     }
                   3444:   else
1.168     vatton   3445:     cssRule = ParseCSSUnit (cssRule, &margin);
1.295     vatton   3446: 
                   3447:   cssRule = CheckImportantRule (cssRule, context);
1.168     vatton   3448:   if (margin.typed_data.value != 0 &&
1.184     vatton   3449:       (margin.typed_data.unit == UNIT_INVALID ||
                   3450:        margin.typed_data.unit == UNIT_BOX))
1.169     vatton   3451:     CSSParseError ("Invalid margin-bottom value", ptr, cssRule);
1.168     vatton   3452:   else if (DoApply)
1.295     vatton   3453:     TtaSetStylePresentation (PRMarginBottom, element, tsch, context, margin);
1.1       cvs      3454:   return (cssRule);
                   3455: }
                   3456: 
                   3457: /*----------------------------------------------------------------------
1.296     vatton   3458:   ParseCSSMarginBottom: parse a CSS margin-bottom attribute
                   3459:   ----------------------------------------------------------------------*/
                   3460: static char *ParseCSSMarginBottom (Element element, PSchema tsch,
                   3461:                                     PresentationContext context,
                   3462:                                     char *cssRule, CSSInfoPtr css,
                   3463:                                     ThotBool isHTML)
                   3464: {
                   3465:   char *ptr = cssRule;
                   3466: 
                   3467:   cssRule = ParseACSSMarginBottom (element, tsch, context, ptr, css, isHTML);
                   3468:   cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-bottom value");
                   3469:   return (cssRule);
                   3470: }
                   3471: 
                   3472: /*----------------------------------------------------------------------
                   3473:   ParseACSSMarginLeft: parse a CSS margin-left attribute string
1.1       cvs      3474:   ----------------------------------------------------------------------*/
1.296     vatton   3475: static char *ParseACSSMarginLeft (Element element, PSchema tsch,
1.78      cvs      3476:                                   PresentationContext context,
1.79      cvs      3477:                                   char *cssRule, CSSInfoPtr css,
1.78      cvs      3478:                                   ThotBool isHTML)
1.1       cvs      3479: {
                   3480:   PresentationValue   margin;
1.168     vatton   3481:   char               *ptr;
1.1       cvs      3482:   
1.82      cvs      3483:   cssRule = SkipBlanksAndComments (cssRule);
1.168     vatton   3484:   ptr = cssRule;
1.1       cvs      3485:   /* first parse the attribute string */
1.164     quint    3486:   if (!strncasecmp (cssRule, "auto", 4))
                   3487:     {
1.184     vatton   3488:       margin.typed_data.unit = VALUE_AUTO;
1.164     quint    3489:       margin.typed_data.value = 0;
                   3490:       margin.typed_data.real = FALSE;
1.288     vatton   3491:       cssRule += 4;
1.295     vatton   3492:       cssRule = CheckImportantRule (cssRule, context);
1.164     quint    3493:     }
                   3494:   else
1.168     vatton   3495:     cssRule = ParseCSSUnit (cssRule, &margin);
1.295     vatton   3496: 
                   3497:   cssRule = CheckImportantRule (cssRule, context);
1.168     vatton   3498:   if (margin.typed_data.value != 0 &&
1.184     vatton   3499:       (margin.typed_data.unit == UNIT_INVALID ||
                   3500:        margin.typed_data.unit == UNIT_BOX))
1.169     vatton   3501:     CSSParseError ("Invalid margin-left value", ptr, cssRule);
1.295     vatton   3502:   else if (DoApply && margin.typed_data.unit != UNIT_INVALID && DoApply)
1.117     vatton   3503:        TtaSetStylePresentation (PRMarginLeft, element, tsch, context, margin);
1.1       cvs      3504:   return (cssRule);
                   3505: }
                   3506: 
                   3507: /*----------------------------------------------------------------------
1.296     vatton   3508:   ParseCSSMarginBottom: parse a CSS margin-bottom attribute
                   3509:   ----------------------------------------------------------------------*/
                   3510: static char *ParseCSSMarginLeft (Element element, PSchema tsch,
                   3511:                                     PresentationContext context,
                   3512:                                     char *cssRule, CSSInfoPtr css,
                   3513:                                     ThotBool isHTML)
                   3514: {
                   3515:   char *ptr = cssRule;
                   3516: 
                   3517:   cssRule = ParseACSSMarginLeft (element, tsch, context, ptr, css, isHTML);
                   3518:   cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-left value");
                   3519:   return (cssRule);
                   3520: }
                   3521: 
                   3522: 
                   3523: /*----------------------------------------------------------------------
                   3524:   ParseACSSMarginRight: parse a CSS margin-right attribute string
1.1       cvs      3525:   ----------------------------------------------------------------------*/
1.296     vatton   3526: static char *ParseACSSMarginRight (Element element, PSchema tsch,
1.78      cvs      3527:                                    PresentationContext context,
1.79      cvs      3528:                                    char *cssRule, CSSInfoPtr css,
1.78      cvs      3529:                                    ThotBool isHTML)
1.1       cvs      3530: {
                   3531:   PresentationValue   margin;
1.168     vatton   3532:   char               *ptr;
1.1       cvs      3533:   
1.82      cvs      3534:   cssRule = SkipBlanksAndComments (cssRule);
1.168     vatton   3535:   ptr = cssRule;
1.1       cvs      3536:   /* first parse the attribute string */
1.164     quint    3537:   if (!strncasecmp (cssRule, "auto", 4))
                   3538:     {
1.184     vatton   3539:       margin.typed_data.unit = VALUE_AUTO;
1.164     quint    3540:       margin.typed_data.value = 0;
                   3541:       margin.typed_data.real = FALSE;
1.288     vatton   3542:       cssRule += 4;
1.295     vatton   3543:       cssRule = CheckImportantRule (cssRule, context);
1.164     quint    3544:     }
                   3545:   else
1.168     vatton   3546:     cssRule = ParseCSSUnit (cssRule, &margin);
1.295     vatton   3547: 
                   3548:   cssRule = CheckImportantRule (cssRule, context);
1.168     vatton   3549:   if (margin.typed_data.value != 0 &&
1.184     vatton   3550:       (margin.typed_data.unit == UNIT_INVALID ||
                   3551:        margin.typed_data.unit == UNIT_BOX))
1.169     vatton   3552:     CSSParseError ("Invalid margin-right value", ptr, cssRule);
1.168     vatton   3553:   else if (DoApply)
1.295     vatton   3554:     TtaSetStylePresentation (PRMarginRight, element, tsch, context, margin);
1.1       cvs      3555:   return (cssRule);
                   3556: }
                   3557: 
                   3558: /*----------------------------------------------------------------------
1.296     vatton   3559:   ParseCSSMarginRight: parse a CSS margin-right attribute string
                   3560:   ----------------------------------------------------------------------*/
                   3561: static char *ParseCSSMarginRight (Element element, PSchema tsch,
                   3562:                                    PresentationContext context,
                   3563:                                    char *cssRule, CSSInfoPtr css,
                   3564:                                    ThotBool isHTML)
                   3565: {
                   3566:   char *ptr = cssRule;
                   3567: 
1.297     vatton   3568:   cssRule = ParseACSSMarginRight (element, tsch, context, ptr, css, isHTML);
1.296     vatton   3569:   cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-right value");
                   3570:   return (cssRule);
                   3571: }
                   3572: 
                   3573: /*----------------------------------------------------------------------
1.59      cvs      3574:   ParseCSSMargin: parse a CSS margin attribute string
1.1       cvs      3575:   ----------------------------------------------------------------------*/
1.79      cvs      3576: static char *ParseCSSMargin (Element element, PSchema tsch,
1.78      cvs      3577:                               PresentationContext context,
1.79      cvs      3578:                               char *cssRule, CSSInfoPtr css,
1.78      cvs      3579:                               ThotBool isHTML)
1.1       cvs      3580: {
1.79      cvs      3581:   char *ptrT, *ptrR, *ptrB, *ptrL;
1.93      vatton   3582:   int   skippedNL;
1.1       cvs      3583: 
1.82      cvs      3584:   ptrT = SkipBlanksAndComments (cssRule);
1.1       cvs      3585:   /* First parse Margin-Top */
1.296     vatton   3586:   ptrR = ParseACSSMarginTop (element, tsch, context, ptrT, css, isHTML);
1.82      cvs      3587:   ptrR = SkipBlanksAndComments (ptrR);
1.301     vatton   3588:   if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.1       cvs      3589:     {
1.93      vatton   3590:       skippedNL = NewLineSkipped;
1.1       cvs      3591:       cssRule = ptrR;
                   3592:       /* apply the Margin-Top to all */
1.296     vatton   3593:       ptrR = ParseACSSMarginRight (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   3594:       NewLineSkipped = skippedNL;
1.296     vatton   3595:       ptrR = ParseACSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   3596:       NewLineSkipped = skippedNL;
1.296     vatton   3597:       ptrR = ParseACSSMarginLeft (element, tsch, context, ptrT, css, isHTML);
1.1       cvs      3598:     }
                   3599:   else
                   3600:     {
                   3601:       /* parse Margin-Right */
1.296     vatton   3602:       ptrB = ParseACSSMarginRight (element, tsch, context, ptrR, css, isHTML);
1.82      cvs      3603:       ptrB = SkipBlanksAndComments (ptrB);
1.301     vatton   3604:       if (*ptrB == ';' || *ptrB == '}' || *ptrB == EOS || *ptrB == ',')
1.1       cvs      3605:        {
1.93      vatton   3606:          skippedNL = NewLineSkipped;
1.1       cvs      3607:          cssRule = ptrB;
                   3608:          /* apply the Margin-Top to Margin-Bottom */
1.296     vatton   3609:          ptrB = ParseACSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   3610:          NewLineSkipped = skippedNL;
1.1       cvs      3611:          /* apply the Margin-Right to Margin-Left */
1.296     vatton   3612:          ptrB = ParseACSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
1.1       cvs      3613:        }
                   3614:       else
                   3615:        {
                   3616:          /* parse Margin-Bottom */
1.296     vatton   3617:          ptrL = ParseACSSMarginBottom (element, tsch, context, ptrB, css, isHTML);
1.82      cvs      3618:          ptrL = SkipBlanksAndComments (ptrL);
1.301     vatton   3619:          if (*ptrL == ';' || *ptrL == '}' || *ptrL == EOS || *ptrL == ',')
1.1       cvs      3620:            {
                   3621:              cssRule = ptrL;
                   3622:              /* apply the Margin-Right to Margin-Left */
1.296     vatton   3623:              ptrL = ParseACSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
1.1       cvs      3624:            }
                   3625:          else
                   3626:            /* parse Margin-Left */
1.296     vatton   3627:            cssRule = ParseACSSMarginLeft (element, tsch, context, ptrL, css, isHTML);
1.82      cvs      3628:          cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      3629:        }
                   3630:     }
                   3631:   return (cssRule);
                   3632: }
                   3633: 
                   3634: /*----------------------------------------------------------------------
1.59      cvs      3635:    ParseCSSPaddingTop: parse a CSS PaddingTop attribute string
1.1       cvs      3636:   ----------------------------------------------------------------------*/
1.79      cvs      3637: static char *ParseCSSPaddingTop (Element element, PSchema tsch,
1.78      cvs      3638:                                 PresentationContext context,
1.79      cvs      3639:                                   char *cssRule, CSSInfoPtr css,
1.78      cvs      3640:                                   ThotBool isHTML)
1.1       cvs      3641: {
1.43      cvs      3642:   PresentationValue   padding;
1.168     vatton   3643:   char               *ptr;
1.43      cvs      3644:   
1.82      cvs      3645:   cssRule = SkipBlanksAndComments (cssRule);
1.168     vatton   3646:   ptr = cssRule;
1.43      cvs      3647:   /* first parse the attribute string */
                   3648:   cssRule = ParseCSSUnit (cssRule, &padding);
1.295     vatton   3649: 
                   3650:   cssRule = CheckImportantRule (cssRule, context);
1.168     vatton   3651:   if (padding.typed_data.value != 0 &&
1.184     vatton   3652:       (padding.typed_data.unit == UNIT_INVALID ||
                   3653:        padding.typed_data.unit == UNIT_BOX))
1.168     vatton   3654:     {
1.169     vatton   3655:       CSSParseError ("Invalid padding-top value", ptr, cssRule);
1.168     vatton   3656:       padding.typed_data.value = 0;
                   3657:     }
                   3658:   else if (DoApply)
1.295     vatton   3659:     TtaSetStylePresentation (PRPaddingTop, element, tsch, context, padding);
1.1       cvs      3660:   return (cssRule);
                   3661: }
                   3662: 
                   3663: /*----------------------------------------------------------------------
1.59      cvs      3664:   ParseCSSPaddingBottom: parse a CSS PaddingBottom attribute string
1.1       cvs      3665:   ----------------------------------------------------------------------*/
1.79      cvs      3666: static char *ParseCSSPaddingBottom (Element element, PSchema tsch,
1.78      cvs      3667:                                      PresentationContext context,
1.79      cvs      3668:                                      char *cssRule, CSSInfoPtr css,
1.78      cvs      3669:                                      ThotBool isHTML)
1.1       cvs      3670: {
1.43      cvs      3671:   PresentationValue   padding;
1.168     vatton   3672:   char               *ptr;
1.43      cvs      3673:   
1.82      cvs      3674:   cssRule = SkipBlanksAndComments (cssRule);
1.168     vatton   3675:   ptr = cssRule;
1.43      cvs      3676:   /* first parse the attribute string */
                   3677:   cssRule = ParseCSSUnit (cssRule, &padding);
1.168     vatton   3678:   if (padding.typed_data.value == 0)
1.184     vatton   3679:     padding.typed_data.unit = UNIT_EM;
1.295     vatton   3680: 
                   3681:   cssRule = CheckImportantRule (cssRule, context);
1.168     vatton   3682:   if (padding.typed_data.value != 0 &&
1.184     vatton   3683:       (padding.typed_data.unit == UNIT_INVALID ||
                   3684:        padding.typed_data.unit == UNIT_BOX))
1.168     vatton   3685:     {
1.169     vatton   3686:       CSSParseError ("Invalid padding-bottom value", ptr, cssRule);
1.168     vatton   3687:       padding.typed_data.value = 0;
                   3688:     }
                   3689:   else if (DoApply)
1.295     vatton   3690:     TtaSetStylePresentation (PRPaddingBottom, element, tsch, context, padding);
1.1       cvs      3691:   return (cssRule);
                   3692: }
                   3693: 
                   3694: /*----------------------------------------------------------------------
1.59      cvs      3695:   ParseCSSPaddingLeft: parse a CSS PaddingLeft attribute string.
1.1       cvs      3696:   ----------------------------------------------------------------------*/
1.79      cvs      3697: static char *ParseCSSPaddingLeft (Element element, PSchema tsch,
1.78      cvs      3698:                                    PresentationContext context,
1.79      cvs      3699:                                    char *cssRule, CSSInfoPtr css,
1.78      cvs      3700:                                    ThotBool isHTML)
1.1       cvs      3701: {
1.43      cvs      3702:   PresentationValue   padding;
1.168     vatton   3703:   char               *ptr;
1.43      cvs      3704:   
1.82      cvs      3705:   cssRule = SkipBlanksAndComments (cssRule);
1.168     vatton   3706:   ptr = cssRule;
1.43      cvs      3707:   /* first parse the attribute string */
                   3708:   cssRule = ParseCSSUnit (cssRule, &padding);
1.168     vatton   3709:   if (padding.typed_data.value == 0)
1.184     vatton   3710:     padding.typed_data.unit = UNIT_EM;
1.295     vatton   3711: 
                   3712:   cssRule = CheckImportantRule (cssRule, context);
1.168     vatton   3713:   if (padding.typed_data.value != 0 &&
1.184     vatton   3714:       (padding.typed_data.unit == UNIT_INVALID ||
                   3715:        padding.typed_data.unit == UNIT_BOX))
1.168     vatton   3716:     {
1.169     vatton   3717:       CSSParseError ("Invalid padding-left value", ptr, cssRule);
1.168     vatton   3718:       padding.typed_data.value = 0;
                   3719:     }
                   3720:   else if (DoApply)
1.295     vatton   3721:     TtaSetStylePresentation (PRPaddingLeft, element, tsch, context, padding);
1.1       cvs      3722:   return (cssRule);
                   3723: }
                   3724: 
                   3725: /*----------------------------------------------------------------------
1.59      cvs      3726:   ParseCSSPaddingRight: parse a CSS PaddingRight attribute string.
1.1       cvs      3727:   ----------------------------------------------------------------------*/
1.79      cvs      3728: static char *ParseCSSPaddingRight (Element element, PSchema tsch,
1.78      cvs      3729:                                     PresentationContext context,
1.79      cvs      3730:                                     char *cssRule, CSSInfoPtr css,
1.78      cvs      3731:                                     ThotBool isHTML)
1.1       cvs      3732: {
1.43      cvs      3733:   PresentationValue   padding;
1.168     vatton   3734:   char               *ptr;
1.43      cvs      3735:   
1.82      cvs      3736:   cssRule = SkipBlanksAndComments (cssRule);
1.168     vatton   3737:   ptr = cssRule;
1.43      cvs      3738:   /* first parse the attribute string */
                   3739:   cssRule = ParseCSSUnit (cssRule, &padding);
1.168     vatton   3740:   if (padding.typed_data.value == 0)
1.184     vatton   3741:     padding.typed_data.unit = UNIT_EM;
1.295     vatton   3742: 
                   3743:   cssRule = CheckImportantRule (cssRule, context);
1.168     vatton   3744:   if (padding.typed_data.value != 0 &&
1.184     vatton   3745:       (padding.typed_data.unit == UNIT_INVALID ||
                   3746:        padding.typed_data.unit == UNIT_BOX))
1.168     vatton   3747:     {
1.169     vatton   3748:       CSSParseError ("Invalid padding-right value", ptr, cssRule);
1.168     vatton   3749:       padding.typed_data.value = 0;
                   3750:     }
                   3751:   else if (DoApply)
1.295     vatton   3752:     TtaSetStylePresentation (PRPaddingRight, element, tsch, context, padding);
1.1       cvs      3753:   return (cssRule);
                   3754: }
                   3755: 
                   3756: /*----------------------------------------------------------------------
1.59      cvs      3757:    ParseCSSPadding: parse a CSS padding attribute string. 
1.1       cvs      3758:   ----------------------------------------------------------------------*/
1.79      cvs      3759: static char *ParseCSSPadding (Element element, PSchema tsch,
1.78      cvs      3760:                                PresentationContext context,
1.79      cvs      3761:                                char *cssRule, CSSInfoPtr css,
1.78      cvs      3762:                                ThotBool isHTML)
1.1       cvs      3763: {
1.79      cvs      3764:   char *ptrT, *ptrR, *ptrB, *ptrL;
1.93      vatton   3765:   int   skippedNL;
1.43      cvs      3766: 
1.82      cvs      3767:   ptrT = SkipBlanksAndComments (cssRule);
1.43      cvs      3768:   /* First parse Padding-Top */
                   3769:   ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
1.82      cvs      3770:   ptrR = SkipBlanksAndComments (ptrR);
                   3771:   if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.43      cvs      3772:     {
1.93      vatton   3773:       skippedNL = NewLineSkipped;
1.43      cvs      3774:       cssRule = ptrR;
                   3775:       /* apply the Padding-Top to all */
                   3776:       ptrR = ParseCSSPaddingRight (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   3777:       NewLineSkipped = skippedNL;
1.43      cvs      3778:       ptrR = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   3779:       NewLineSkipped = skippedNL;
1.43      cvs      3780:       ptrR = ParseCSSPaddingLeft (element, tsch, context, ptrT, css, isHTML);
                   3781:     }
                   3782:   else
                   3783:     {
                   3784:       /* parse Padding-Right */
                   3785:       ptrB = ParseCSSPaddingRight (element, tsch, context, ptrR, css, isHTML);
1.82      cvs      3786:       ptrB = SkipBlanksAndComments (ptrB);
                   3787:       if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.43      cvs      3788:        {
1.93      vatton   3789:          skippedNL = NewLineSkipped;
1.43      cvs      3790:          cssRule = ptrB;
                   3791:          /* apply the Padding-Top to Padding-Bottom */
                   3792:          ptrB = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   3793:          NewLineSkipped = skippedNL;
1.43      cvs      3794:          /* apply the Padding-Right to Padding-Left */
                   3795:          ptrB = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
                   3796:        }
                   3797:       else
                   3798:        {
                   3799:          /* parse Padding-Bottom */
                   3800:          ptrL = ParseCSSPaddingBottom (element, tsch, context, ptrB, css, isHTML);
1.82      cvs      3801:          ptrL = SkipBlanksAndComments (ptrL);
                   3802:          if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.43      cvs      3803:            {
                   3804:              cssRule = ptrL;
                   3805:              /* apply the Padding-Right to Padding-Left */
                   3806:              ptrL = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
                   3807:            }
                   3808:          else
                   3809:            /* parse Padding-Left */
                   3810:            cssRule = ParseCSSPaddingLeft (element, tsch, context, ptrL, css, isHTML);
1.82      cvs      3811:          cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      3812:        }
                   3813:     }
1.1       cvs      3814:   return (cssRule);
                   3815: }
                   3816: 
                   3817: /*----------------------------------------------------------------------
1.59      cvs      3818:    ParseCSSForeground: parse a CSS foreground attribute 
1.1       cvs      3819:   ----------------------------------------------------------------------*/
1.79      cvs      3820: static char *ParseCSSForeground (Element element, PSchema tsch,
1.78      cvs      3821:                                          PresentationContext context,
1.79      cvs      3822:                                          char *cssRule,
1.78      cvs      3823:                                          CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      3824: {
1.117     vatton   3825:   PresentationValue   best;
1.262     vatton   3826:   char               *p;
1.1       cvs      3827: 
1.262     vatton   3828:   p = cssRule;
1.117     vatton   3829:   cssRule = ParseCSSColor (cssRule, &best);
1.295     vatton   3830:   cssRule = CheckImportantRule (cssRule, context);
1.184     vatton   3831:   if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117     vatton   3832:      {
1.295     vatton   3833:         if (*cssRule != EOS && *cssRule !=';')
1.262     vatton   3834:         {
                   3835:           cssRule = SkipProperty (cssRule, FALSE);
                   3836:           CSSParseError ("Invalid value", p, cssRule);
                   3837:         }
                   3838:        else
                   3839:         /* install the new presentation */
                   3840:         TtaSetStylePresentation (PRForeground, element, tsch, context, best);
1.117     vatton   3841:      }
1.1       cvs      3842:    return (cssRule);
                   3843: }
                   3844: 
                   3845: /*----------------------------------------------------------------------
1.59      cvs      3846:   ParseCSSBackgroundColor: parse a CSS background color attribute 
1.1       cvs      3847:   ----------------------------------------------------------------------*/
1.79      cvs      3848: static char *ParseCSSBackgroundColor (Element element, PSchema tsch,
1.78      cvs      3849:                                        PresentationContext context,
1.79      cvs      3850:                                        char *cssRule,
1.78      cvs      3851:                                        CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      3852: {
                   3853:   PresentationValue     best;
                   3854: 
1.184     vatton   3855:   best.typed_data.unit = UNIT_INVALID;
1.1       cvs      3856:   best.typed_data.real = FALSE;
1.198     vatton   3857:   if (!strncasecmp (cssRule, "transparent", 11))
1.1       cvs      3858:     {
1.184     vatton   3859:       best.typed_data.value = PATTERN_NONE;
                   3860:       best.typed_data.unit = UNIT_REL;
1.295     vatton   3861:       cssRule = SkipWord (cssRule);
                   3862:       cssRule = CheckImportantRule (cssRule, context);
1.116     vatton   3863:       if (DoApply)
1.295     vatton   3864:        TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
                   3865:      }
1.1       cvs      3866:   else
                   3867:     {
                   3868:       cssRule = ParseCSSColor (cssRule, &best);
1.295     vatton   3869:       cssRule = CheckImportantRule (cssRule, context);
1.184     vatton   3870:       if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.1       cvs      3871:        {
                   3872:          /* install the new presentation. */
                   3873:          TtaSetStylePresentation (PRBackground, element, tsch, context, best);
1.59      cvs      3874:          /* thot specificity: need to set fill pattern for background color */
1.184     vatton   3875:          best.typed_data.value = PATTERN_BACKGROUND;
                   3876:          best.typed_data.unit = UNIT_REL;
1.1       cvs      3877:          TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
                   3878:          best.typed_data.value = 1;
1.184     vatton   3879:          best.typed_data.unit = UNIT_REL;
1.1       cvs      3880:          TtaSetStylePresentation (PRShowBox, element, tsch, context, best);
                   3881:        }
                   3882:     }
                   3883:   return (cssRule);
                   3884: }
                   3885: 
1.63      cvs      3886: /*----------------------------------------------------------------------
1.65      cvs      3887:   ParseSVGStroke: parse a SVG stroke property
                   3888:   ----------------------------------------------------------------------*/
1.79      cvs      3889: static char *ParseSVGStroke (Element element, PSchema tsch,
                   3890:                             PresentationContext context, char *cssRule,
                   3891:                             CSSInfoPtr css, ThotBool isHTML)
1.65      cvs      3892: {
                   3893:   PresentationValue     best;
1.245     quint    3894:   char                  *url;
1.65      cvs      3895: 
1.184     vatton   3896:   best.typed_data.unit = UNIT_INVALID;
1.65      cvs      3897:   best.typed_data.real = FALSE;
1.82      cvs      3898:   if (!strncasecmp (cssRule, "none", 4))
1.65      cvs      3899:     {
                   3900:       best.typed_data.value = -2;  /* -2 means transparent */
1.184     vatton   3901:       best.typed_data.unit = UNIT_REL;
1.65      cvs      3902:       cssRule = SkipWord (cssRule);
                   3903:     }
1.245     quint    3904:   else if (!strncasecmp (cssRule, "currentColor", 12))
                   3905:     {
1.293     quint    3906:       best.typed_data.unit = VALUE_INHERIT;
                   3907:       cssRule = SkipWord (cssRule);
1.245     quint    3908:     }
                   3909:   else if (!strncasecmp (cssRule, "url", 3))
                   3910:     {  
                   3911:       cssRule += 3;
                   3912:       cssRule = ParseCSSUrl (cssRule, &url);
                   3913:       /* **** do something with the url ***** */;
                   3914:       TtaFreeMemory (url);
                   3915:       /* **** caution: another color value may follow the uri (in case
                   3916:         the uri could ne be dereferenced) *** */
                   3917:     }
1.65      cvs      3918:   else
1.293     quint    3919:     cssRule = ParseCSSColor (cssRule, &best);
                   3920: 
1.295     vatton   3921:   cssRule = CheckImportantRule (cssRule, context);
1.293     quint    3922:   if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.295     vatton   3923:     /* install the new presentation */
                   3924:     TtaSetStylePresentation (PRForeground, element, tsch, context, best);
1.65      cvs      3925:   return (cssRule);
                   3926: }
                   3927: 
                   3928: /*----------------------------------------------------------------------
1.63      cvs      3929:   ParseSVGFill: parse a SVG fill property
                   3930:   ----------------------------------------------------------------------*/
1.79      cvs      3931: static char *ParseSVGFill (Element element, PSchema tsch,
                   3932:                           PresentationContext context, char *cssRule,
                   3933:                           CSSInfoPtr css, ThotBool isHTML)
1.63      cvs      3934: {
                   3935:   PresentationValue     best;
1.245     quint    3936:   char                  *url;
1.63      cvs      3937: 
1.184     vatton   3938:   best.typed_data.unit = UNIT_INVALID;
1.63      cvs      3939:   best.typed_data.real = FALSE;
1.82      cvs      3940:   if (!strncasecmp (cssRule, "none", 4))
1.63      cvs      3941:     {
1.184     vatton   3942:       best.typed_data.value = PATTERN_NONE;
                   3943:       best.typed_data.unit = UNIT_REL;
1.295     vatton   3944:       cssRule = CheckImportantRule (cssRule, context);
1.116     vatton   3945:       if (DoApply)
1.295     vatton   3946:        TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.65      cvs      3947:       cssRule = SkipWord (cssRule);
1.294     vatton   3948:       return (cssRule);
1.63      cvs      3949:     }
1.245     quint    3950:   else if (!strncasecmp (cssRule, "currentColor", 12))
                   3951:     {
1.293     quint    3952:       best.typed_data.unit = VALUE_INHERIT;
                   3953:       cssRule = SkipWord (cssRule);
1.245     quint    3954:     }
                   3955:   else if (!strncasecmp (cssRule, "url", 3))
                   3956:     {  
                   3957:       cssRule += 3;
                   3958:       cssRule = ParseCSSUrl (cssRule, &url);
                   3959:       /* **** do something with the url ***** */;
                   3960:       TtaFreeMemory (url);
                   3961:       /* **** caution: another color value may follow the uri (in case
                   3962:         the uri could ne be dereferenced) *** */
                   3963:     }
1.63      cvs      3964:   else
1.293     quint    3965:       cssRule = ParseCSSColor (cssRule, &best);
                   3966: 
1.295     vatton   3967:   cssRule = CheckImportantRule (cssRule, context);
1.293     quint    3968:   if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.63      cvs      3969:     {
1.293     quint    3970:       /* install the new presentation. */
                   3971:       TtaSetStylePresentation (PRBackground, element, tsch, context, best);
                   3972:       /* thot specificity: need to set fill pattern for background color */
                   3973:       best.typed_data.value = PATTERN_BACKGROUND;
                   3974:       best.typed_data.unit = UNIT_REL;
                   3975:       TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.63      cvs      3976:     }
                   3977:   return (cssRule);
                   3978: }
1.161     quint    3979: 
1.155     cheyroul 3980: /*----------------------------------------------------------------------
                   3981:   ParseSVGOpacity: parse a SVG fill property
                   3982:   ----------------------------------------------------------------------*/
                   3983: static char *ParseSVGOpacity (Element element, PSchema tsch,
                   3984:                              PresentationContext context, char *cssRule,
                   3985:                              CSSInfoPtr css, ThotBool isHTML)
                   3986: {
                   3987:   PresentationValue     best;
1.63      cvs      3988: 
1.184     vatton   3989:   best.typed_data.unit = UNIT_INVALID;
1.155     cheyroul 3990:   best.typed_data.real = FALSE;
                   3991:   cssRule = ParseClampedUnit (cssRule, &best);
1.295     vatton   3992:   cssRule = CheckImportantRule (cssRule, context);
1.155     cheyroul 3993:   if (DoApply)
1.295     vatton   3994:     /* install the new presentation. */
                   3995:     TtaSetStylePresentation (PROpacity, element, tsch, context, best);
1.155     cheyroul 3996:   return (cssRule);
                   3997: }
1.170     cheyroul 3998: /*----------------------------------------------------------------------
                   3999:   ParseSVGOpacity: parse a SVG fill property
                   4000:   ----------------------------------------------------------------------*/
                   4001: static char *ParseSVGStrokeOpacity (Element element, PSchema tsch,
                   4002:                              PresentationContext context, char *cssRule,
                   4003:                              CSSInfoPtr css, ThotBool isHTML)
                   4004: {
                   4005:   PresentationValue     best;
1.161     quint    4006: 
1.184     vatton   4007:   best.typed_data.unit = UNIT_INVALID;
1.170     cheyroul 4008:   best.typed_data.real = FALSE;
                   4009:   cssRule = ParseClampedUnit (cssRule, &best);
1.295     vatton   4010:   cssRule = CheckImportantRule (cssRule, context);
1.170     cheyroul 4011:   if (DoApply)
1.295     vatton   4012:     /* install the new presentation. */
                   4013:     TtaSetStylePresentation (PRStrokeOpacity, element, tsch, context, best);
1.170     cheyroul 4014:   return (cssRule);
                   4015: }
                   4016: /*----------------------------------------------------------------------
                   4017:   ParseSVGOpacity: parse a SVG fill property
                   4018:   ----------------------------------------------------------------------*/
                   4019: static char *ParseSVGFillOpacity (Element element, PSchema tsch,
                   4020:                              PresentationContext context, char *cssRule,
                   4021:                              CSSInfoPtr css, ThotBool isHTML)
                   4022: {
                   4023:   PresentationValue     best;
                   4024: 
1.184     vatton   4025:   best.typed_data.unit = UNIT_INVALID;
1.170     cheyroul 4026:   best.typed_data.real = FALSE;
                   4027:   cssRule = ParseClampedUnit (cssRule, &best);
1.295     vatton   4028:   cssRule = CheckImportantRule (cssRule, context);
1.170     cheyroul 4029:   if (DoApply)
1.295     vatton   4030:     /* install the new presentation. */
                   4031:     TtaSetStylePresentation (PRFillOpacity, element, tsch, context, best);
1.170     cheyroul 4032:   return (cssRule);
                   4033: }
1.207     vatton   4034: 
1.1       cvs      4035: /*----------------------------------------------------------------------
1.217     vatton   4036:    GetCSSBackgroundURL searches a CSS BackgroundImage url within
                   4037:    the cssRule.
                   4038:    Returns NULL or a new allocated url string.
                   4039:   ----------------------------------------------------------------------*/
                   4040: char *GetCSSBackgroundURL (char *cssRule)
                   4041: {
                   4042:   char            *b, *url;
                   4043: 
                   4044:   url = NULL;
                   4045:   b = strstr (cssRule, "url");
                   4046:   if (b)
1.290     gully    4047:     b = ParseCSSUrl (b, &url);
1.217     vatton   4048:   return (url);
                   4049: }
                   4050: 
                   4051: /*----------------------------------------------------------------------
1.306     quint    4052:    ParseCSSContent: parse the value of property "content"
1.217     vatton   4053:   ----------------------------------------------------------------------*/
                   4054: static char *ParseCSSContent (Element element, PSchema tsch,
                   4055:                              PresentationContext context, char *cssRule,
                   4056:                              CSSInfoPtr css, ThotBool isHTML)
                   4057: {
                   4058:   char      *p, quoteChar, *url;
                   4059: 
                   4060:   cssRule = SkipBlanksAndComments (cssRule);
                   4061:   p = cssRule;
                   4062:   if (!strncasecmp (cssRule, "url", 3))
                   4063:     {  
                   4064:       cssRule += 3;
                   4065:       cssRule = ParseCSSUrl (cssRule, &url);
                   4066:       TtaFreeMemory (url);
                   4067:     }
                   4068:    else if (*cssRule == '"' || *cssRule == '\'')
                   4069:      {
                   4070:        quoteChar = *cssRule;
                   4071:        cssRule++;
                   4072:        cssRule = SkipQuotedString (cssRule, quoteChar);
1.259     vatton   4073:        cssRule = SkipBlanksAndComments (cssRule);
1.253     vatton   4074:        if (*cssRule != EOS && *cssRule !=';')
1.260     vatton   4075:         cssRule = SkipProperty (cssRule, FALSE);
1.217     vatton   4076:      }
                   4077:   else
1.260     vatton   4078:     cssRule = SkipProperty (cssRule, FALSE);
1.295     vatton   4079:   cssRule = CheckImportantRule (cssRule, context);
1.217     vatton   4080:   return (cssRule);
                   4081: }
1.1       cvs      4082: 
                   4083: /*----------------------------------------------------------------------
1.59      cvs      4084:   ParseCSSBackgroundImage: parse a CSS BackgroundImage attribute string.
1.1       cvs      4085:   ----------------------------------------------------------------------*/
1.79      cvs      4086: static char *ParseCSSBackgroundImage (Element element, PSchema tsch,
1.207     vatton   4087:                                      PresentationContext ctxt,
1.79      cvs      4088:                                      char *cssRule, CSSInfoPtr css,
                   4089:                                      ThotBool isHTML)
1.1       cvs      4090: {
1.49      cvs      4091:   PresentationValue          image, value;
1.148     vatton   4092: 
1.82      cvs      4093:   cssRule = SkipBlanksAndComments (cssRule);
1.161     quint    4094:   if (!strncasecmp (cssRule, "none", 4))
                   4095:     {
1.260     vatton   4096:       cssRule += 4;
1.276     vatton   4097:       cssRule = CheckImportantRule (cssRule, ctxt);
1.247     quint    4098:       if (DoApply)
                   4099:        {
                   4100:          /* no background image */
                   4101:          image.pointer = NULL;
1.302     quint    4102:          TtaSetStylePresentation (PRBackgroundPicture, element, tsch, ctxt,
                   4103:                                   image);
1.247     quint    4104:          /* no background color */
                   4105:          value.typed_data.unit = UNIT_INVALID;
                   4106:          value.typed_data.real = FALSE;
                   4107:          value.typed_data.value = PATTERN_NONE;
                   4108:          value.typed_data.unit = UNIT_REL;
                   4109:          TtaSetStylePresentation (PRFillPattern, element, tsch, ctxt, value);
                   4110:        }
1.161     quint    4111:     }
                   4112:   else if (!strncasecmp (cssRule, "url", 3))
1.1       cvs      4113:     {  
                   4114:       cssRule += 3;
1.302     quint    4115:       cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
                   4116:                             PRBackgroundPicture);
1.207     vatton   4117:       if (ctxt->destroy)
1.302     quint    4118:        if (TtaGetStylePresentation (PRFillPattern, element, tsch, ctxt,
                   4119:                                     &value) < 0)
1.1       cvs      4120:            {
                   4121:              /* there is no FillPattern rule -> remove ShowBox rule */
                   4122:              value.typed_data.value = 1;
1.184     vatton   4123:              value.typed_data.unit = UNIT_REL;
1.1       cvs      4124:              value.typed_data.real = FALSE;
1.207     vatton   4125:              TtaSetStylePresentation (PRShowBox, element, tsch, ctxt, value);
1.1       cvs      4126:            }
1.18      cvs      4127:     }
                   4128:   return (cssRule);
                   4129: }
                   4130: 
                   4131: /*----------------------------------------------------------------------
1.295     vatton   4132:   ParseACSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
1.18      cvs      4133:   ----------------------------------------------------------------------*/
1.295     vatton   4134: static char *ParseACSSBackgroundRepeat (Element element, PSchema tsch,
                   4135:                                        PresentationContext ctxt,
                   4136:                                        char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18      cvs      4137: {
                   4138:   PresentationValue   repeat;
                   4139: 
1.184     vatton   4140:   repeat.typed_data.value = REALSIZE;
1.191     vatton   4141:   repeat.typed_data.unit = UNIT_BOX;
1.18      cvs      4142:   repeat.typed_data.real = FALSE;
1.82      cvs      4143:   cssRule = SkipBlanksAndComments (cssRule);
                   4144:   if (!strncasecmp (cssRule, "no-repeat", 9))
1.184     vatton   4145:     repeat.typed_data.value = REALSIZE;
1.82      cvs      4146:   else if (!strncasecmp (cssRule, "repeat-y", 8))
1.265     vatton   4147:     repeat.typed_data.value = YREPEAT;
1.82      cvs      4148:   else if (!strncasecmp (cssRule, "repeat-x", 8))
1.265     vatton   4149:     repeat.typed_data.value = XREPEAT;
1.82      cvs      4150:   else if (!strncasecmp (cssRule, "repeat", 6))
1.184     vatton   4151:     repeat.typed_data.value = REPEAT;
1.18      cvs      4152:   else
                   4153:     return (cssRule);
                   4154: 
1.295     vatton   4155:   cssRule = SkipWord (cssRule);
                   4156:   /* check if it's an important rule */
                   4157:   cssRule = CheckImportantRule (cssRule, ctxt);
1.116     vatton   4158:   if (DoApply)
1.295     vatton   4159:     /* install the new presentation */
                   4160:     TtaSetStylePresentation (PRPictureMode, element, tsch, ctxt, repeat);
                   4161:   return (cssRule);
                   4162: }
                   4163: 
                   4164: /*----------------------------------------------------------------------
                   4165:   ParseCSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
                   4166:   ----------------------------------------------------------------------*/
                   4167: static char *ParseCSSBackgroundRepeat (Element element, PSchema tsch,
                   4168:                                       PresentationContext ctxt,
                   4169:                                       char *cssRule, CSSInfoPtr css,
                   4170:                                       ThotBool isHTML)
                   4171: {
                   4172:   char     *ptr;
                   4173: 
                   4174:   ptr = cssRule;
                   4175:   cssRule = ParseACSSBackgroundRepeat (element, tsch, ctxt,
                   4176:                                       cssRule, css, isHTML);
                   4177:   if (ptr = cssRule)
1.117     vatton   4178:     {
1.295     vatton   4179:       cssRule = SkipValue ("Invalid background-repeat value", cssRule);
1.117     vatton   4180:       /* check if it's an important rule */
1.276     vatton   4181:       cssRule = CheckImportantRule (cssRule, ctxt);
1.117     vatton   4182:     }
1.295     vatton   4183:   return cssRule;
1.18      cvs      4184: }
                   4185: 
                   4186: /*----------------------------------------------------------------------
1.295     vatton   4187:    ParseACSSBackgroundAttachment: parse a CSS BackgroundAttachment
1.18      cvs      4188:    attribute string.                                          
                   4189:   ----------------------------------------------------------------------*/
1.295     vatton   4190: static char *ParseACSSBackgroundAttachment (Element element, PSchema tsch,
1.207     vatton   4191:                                           PresentationContext ctxt,
1.79      cvs      4192:                                           char *cssRule, CSSInfoPtr css,
                   4193:                                           ThotBool isHTML)
1.18      cvs      4194: {
1.200     vatton   4195:   char     *ptr;
                   4196: 
1.163     quint    4197:   cssRule = SkipBlanksAndComments (cssRule);
                   4198:   if (!strncasecmp (cssRule, "scroll", 6))
1.199     vatton   4199:     {
                   4200:       /* force no-repeat for that background image */
1.200     vatton   4201:       ptr = "no-repeat";
1.295     vatton   4202:       ParseACSSBackgroundRepeat (element, tsch, ctxt, ptr, css, isHTML);
1.199     vatton   4203:       cssRule = SkipWord (cssRule);
                   4204:     }
1.163     quint    4205:   else if (!strncasecmp (cssRule, "fixed", 5))
1.199     vatton   4206:     {
                   4207:       /* force no-repeat for that background image */
1.201     vatton   4208:       ptr = "no-repeat";
1.295     vatton   4209:       ParseACSSBackgroundRepeat (element, tsch, ctxt, ptr, css, isHTML);
1.199     vatton   4210:       cssRule = SkipWord (cssRule);
                   4211:     }
1.163     quint    4212:   return (cssRule);
1.1       cvs      4213: }
                   4214: 
                   4215: /*----------------------------------------------------------------------
1.295     vatton   4216:    ParseCSSBackgroundAttachment: parse a CSS BackgroundAttachment
                   4217:    attribute string.                                          
                   4218:   ----------------------------------------------------------------------*/
                   4219: static char *ParseCSSBackgroundAttachment (Element element, PSchema tsch,
                   4220:                                           PresentationContext ctxt,
                   4221:                                           char *cssRule, CSSInfoPtr css,
                   4222:                                           ThotBool isHTML)
                   4223: {
                   4224:   char     *ptr;
                   4225: 
                   4226:   ptr = cssRule;
                   4227:   cssRule = ParseACSSBackgroundAttachment (element, tsch, ctxt,
                   4228:                                           cssRule, css, isHTML);
                   4229:   if (ptr == cssRule)
                   4230:     {
                   4231:       cssRule = SkipValue ("Invalid background-attachement value", cssRule);
                   4232:       /* check if it's an important rule */
                   4233:       cssRule = CheckImportantRule (cssRule, ctxt);
                   4234:     }
                   4235:   return cssRule;
                   4236: }
                   4237: 
                   4238: /*----------------------------------------------------------------------
1.279     vatton   4239:    ParseACSSBackgroundPosition: parse a CSS BackgroundPosition
1.1       cvs      4240:    attribute string.                                          
                   4241:   ----------------------------------------------------------------------*/
1.279     vatton   4242: static char *ParseACSSBackgroundPosition (Element element, PSchema tsch,
                   4243:                                          PresentationContext ctxt,
                   4244:                                          char *cssRule, CSSInfoPtr css,
                   4245:                                          ThotBool isHTML)
1.1       cvs      4246: {
1.18      cvs      4247:   PresentationValue     repeat;
1.200     vatton   4248:   char                 *ptr;
1.18      cvs      4249:   ThotBool              ok;
1.1       cvs      4250: 
1.163     quint    4251:   cssRule = SkipBlanksAndComments (cssRule);
                   4252:   ok = TRUE;
                   4253:   if (!strncasecmp (cssRule, "left", 4))
                   4254:     cssRule = SkipWord (cssRule);
                   4255:   else if (!strncasecmp (cssRule, "right", 5))
                   4256:     cssRule = SkipWord (cssRule);
                   4257:   else if (!strncasecmp (cssRule, "center", 6))
                   4258:     cssRule = SkipWord (cssRule);
                   4259:   else if (!strncasecmp (cssRule, "top", 3))
                   4260:     cssRule = SkipWord (cssRule);
                   4261:   else if (!strncasecmp (cssRule, "bottom", 6))
                   4262:     cssRule = SkipWord (cssRule);
1.279     vatton   4263:   else if (isdigit (*cssRule) || *cssRule == '.' || *cssRule == '-')
1.191     vatton   4264:     {
1.206     vatton   4265:       while (*cssRule != EOS && *cssRule != SPACE &&
                   4266:             *cssRule != ',' && *cssRule != ';')
                   4267:        cssRule++;
1.191     vatton   4268:     }
1.163     quint    4269:   else
                   4270:     ok = FALSE;
                   4271: 
                   4272:   if (ok && DoApply)
1.148     vatton   4273:     {
1.199     vatton   4274:       /* force no-repeat for that background image */
1.200     vatton   4275:       ptr = "no-repeat";
1.295     vatton   4276:       ParseACSSBackgroundRepeat (element, tsch, ctxt, ptr, css, isHTML);
1.163     quint    4277:       /* force realsize for the background image */
1.184     vatton   4278:       repeat.typed_data.value = REALSIZE;
                   4279:       repeat.typed_data.unit = UNIT_REL;
1.163     quint    4280:       repeat.typed_data.real = FALSE;
                   4281:       /* check if it's an important rule */
1.276     vatton   4282:       cssRule = CheckImportantRule (cssRule, ctxt);
1.207     vatton   4283:       /*TtaSetStylePresentation (PRPictureMode, element, tsch, ctxt, repeat);*/
1.279     vatton   4284:     }
                   4285:   cssRule = SkipBlanksAndComments (cssRule);
                   4286:   return (cssRule);
                   4287: }
1.218     vatton   4288: 
1.279     vatton   4289: /*----------------------------------------------------------------------
                   4290:    ParseCSSBackgroundPosition: parse a CSS BackgroundPosition
                   4291:    attribute string.                                          
                   4292:   ----------------------------------------------------------------------*/
                   4293: static char *ParseCSSBackgroundPosition (Element element, PSchema tsch,
                   4294:                                         PresentationContext ctxt,
                   4295:                                         char *cssRule, CSSInfoPtr css,
                   4296:                                         ThotBool isHTML)
                   4297: {
1.295     vatton   4298:   char     *ptr;
                   4299: 
                   4300:   ptr = cssRule;
1.279     vatton   4301:   cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt,
                   4302:                                         cssRule, css, isHTML);
1.295     vatton   4303:   if (ptr == cssRule)
1.279     vatton   4304:     cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt,
                   4305:                                           cssRule, css, isHTML);
1.295     vatton   4306:   if (ptr == cssRule)
                   4307:     {
                   4308:       cssRule = SkipValue ("Invalid background-position value", cssRule);
                   4309:       /* check if it's an important rule */
                   4310:       cssRule = CheckImportantRule (cssRule, ctxt);
                   4311:     }
1.298     vatton   4312:   else if (*cssRule !=  ';' && *cssRule != EOS)
                   4313:     {
                   4314:       /* possible second value */
                   4315:       ptr = cssRule;
                   4316:       cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt,
                   4317:                                             cssRule, css, isHTML);
                   4318:       if (ptr == cssRule)
                   4319:        cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt,
                   4320:                                               cssRule, css, isHTML);
                   4321:       if (ptr == cssRule)
                   4322:        {
                   4323:          cssRule = SkipValue ("Invalid background-position value", cssRule);
                   4324:          /* check if it's an important rule */
                   4325:          cssRule = CheckImportantRule (cssRule, ctxt);
                   4326:        }
                   4327:     }
1.163     quint    4328:   return (cssRule);
1.18      cvs      4329: }
                   4330: 
                   4331: /*----------------------------------------------------------------------
1.59      cvs      4332:    ParseCSSBackground: parse a CSS background attribute 
1.18      cvs      4333:   ----------------------------------------------------------------------*/
1.79      cvs      4334: static char *ParseCSSBackground (Element element, PSchema tsch,
1.207     vatton   4335:                                 PresentationContext ctxt, char *cssRule,
1.79      cvs      4336:                                 CSSInfoPtr css, ThotBool isHTML)
1.18      cvs      4337: {
1.79      cvs      4338:   char     *ptr;
1.93      vatton   4339:   int   skippedNL;
1.18      cvs      4340: 
1.82      cvs      4341:   cssRule = SkipBlanksAndComments (cssRule);
1.301     vatton   4342:   while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.18      cvs      4343:     {
1.71      cvs      4344:       /* perhaps a Background Image */
1.198     vatton   4345:       if (!strncasecmp (cssRule, "url", 3) || !strncasecmp (cssRule, "none", 4))
1.207     vatton   4346:          cssRule = ParseCSSBackgroundImage (element, tsch, ctxt, cssRule,
1.63      cvs      4347:                                            css, isHTML);
1.18      cvs      4348:       /* perhaps a Background Attachment */
1.82      cvs      4349:       else if (!strncasecmp (cssRule, "scroll", 6) ||
                   4350:                !strncasecmp (cssRule, "fixed", 5))
1.295     vatton   4351:        cssRule = ParseACSSBackgroundAttachment (element, tsch, ctxt,
1.63      cvs      4352:                                                cssRule, css, isHTML);
1.18      cvs      4353:       /* perhaps a Background Repeat */
1.82      cvs      4354:       else if (!strncasecmp (cssRule, "no-repeat", 9) ||
                   4355:                !strncasecmp (cssRule, "repeat-y", 8)  ||
                   4356:                !strncasecmp (cssRule, "repeat-x", 8)  ||
                   4357:                !strncasecmp (cssRule, "repeat", 6))
1.295     vatton   4358:        cssRule = ParseACSSBackgroundRepeat (element, tsch, ctxt,
                   4359:                                             cssRule, css, isHTML);
1.18      cvs      4360:       /* perhaps a Background Position */
1.82      cvs      4361:       else if (!strncasecmp (cssRule, "left", 4)   ||
                   4362:                !strncasecmp (cssRule, "right", 5)  ||
                   4363:                !strncasecmp (cssRule, "center", 6) ||
                   4364:                !strncasecmp (cssRule, "top", 3)    ||
                   4365:                !strncasecmp (cssRule, "bottom", 6) ||
1.279     vatton   4366:                isdigit (*cssRule) || *cssRule == '.' || *cssRule == '-')
                   4367:            cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt,
1.63      cvs      4368:                                                 cssRule, css, isHTML);
1.18      cvs      4369:       /* perhaps a Background Color */
                   4370:       else
                   4371:        {
1.93      vatton   4372:          skippedNL = NewLineSkipped;
1.18      cvs      4373:          /* check if the rule has been found */
                   4374:          ptr = cssRule;
1.207     vatton   4375:          cssRule = ParseCSSBackgroundColor (element, tsch, ctxt,
1.82      cvs      4376:                                             cssRule, css, isHTML);
1.43      cvs      4377:          if (ptr == cssRule)
1.93      vatton   4378:            {
                   4379:              NewLineSkipped = skippedNL;
                   4380:              /* rule not found */
1.234     vatton   4381:              cssRule = SkipProperty (cssRule, FALSE);
1.93      vatton   4382:            }
1.18      cvs      4383:        }
1.82      cvs      4384:       cssRule = SkipBlanksAndComments (cssRule);
1.18      cvs      4385:     }
                   4386:    return (cssRule);
                   4387: }
                   4388: 
1.59      cvs      4389: /*----------------------------------------------------------------------
1.60      cvs      4390:  ParseCSSPageBreakBefore: parse a CSS page-break-before attribute 
1.59      cvs      4391:   ----------------------------------------------------------------------*/
1.79      cvs      4392: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
1.207     vatton   4393:                                      PresentationContext ctxt, char *cssRule,
1.79      cvs      4394:                                      CSSInfoPtr css, ThotBool isHTML)
1.59      cvs      4395: {
                   4396:   PresentationValue   page;
                   4397: 
1.184     vatton   4398:   page.typed_data.unit = UNIT_INVALID;
1.59      cvs      4399:   page.typed_data.real = FALSE;
1.82      cvs      4400:   cssRule = SkipBlanksAndComments (cssRule);
                   4401:   if (!strncasecmp (cssRule, "auto", 4))
1.184     vatton   4402:     page.typed_data.value = PageAuto;
1.82      cvs      4403:   else if (!strncasecmp (cssRule, "always", 6))
1.59      cvs      4404:     {
1.184     vatton   4405:       page.typed_data.unit = UNIT_REL;
                   4406:       page.typed_data.value = PageAlways;
1.59      cvs      4407:     }
1.82      cvs      4408:   else if (!strncasecmp (cssRule, "avoid", 5))
1.59      cvs      4409:     {
1.184     vatton   4410:       page.typed_data.unit = UNIT_REL;
                   4411:       page.typed_data.value = PageAvoid;
1.59      cvs      4412:     }
1.82      cvs      4413:   else if (!strncasecmp (cssRule, "left", 4))
1.59      cvs      4414:     {
1.184     vatton   4415:       page.typed_data.unit = UNIT_REL;
                   4416:       page.typed_data.value = PageLeft;
1.59      cvs      4417:     }
1.82      cvs      4418:   else if (!strncasecmp (cssRule, "right", 5))
1.59      cvs      4419:     {
1.184     vatton   4420:       page.typed_data.unit = UNIT_REL;
                   4421:       page.typed_data.value = PageRight;
1.59      cvs      4422:     }
1.82      cvs      4423:   else if (!strncasecmp (cssRule, "inherit", 7))
1.59      cvs      4424:     {
1.293     quint    4425:       page.typed_data.unit = VALUE_INHERIT;
1.184     vatton   4426:       page.typed_data.value = PageInherit;
1.59      cvs      4427:     }
                   4428:   cssRule = SkipWord (cssRule);
1.295     vatton   4429:   /* check if it's an important rule */
                   4430:   cssRule = CheckImportantRule (cssRule, ctxt);
1.59      cvs      4431:   /* install the new presentation */
1.295     vatton   4432:   if (DoApply &&
                   4433:       ((page.typed_data.unit == UNIT_REL && page.typed_data.value == PageAlways)
                   4434:        || page.typed_data.unit == VALUE_INHERIT))
                   4435:     TtaSetStylePresentation (PRPageBefore, element, tsch, ctxt, page);
1.59      cvs      4436:   return (cssRule);
                   4437: }
                   4438: 
                   4439: /*----------------------------------------------------------------------
1.60      cvs      4440:  ParseCSSPageBreakAfter: parse a CSS page-break-after attribute 
1.59      cvs      4441:   ----------------------------------------------------------------------*/
1.79      cvs      4442: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
1.207     vatton   4443:                                     PresentationContext ctxt,
1.79      cvs      4444:                                     char *cssRule, CSSInfoPtr css,
                   4445:                                     ThotBool isHTML)
1.59      cvs      4446: {
                   4447:   PresentationValue   page;
                   4448: 
1.184     vatton   4449:   page.typed_data.unit = UNIT_INVALID;
1.59      cvs      4450:   page.typed_data.real = FALSE;
1.82      cvs      4451:   cssRule = SkipBlanksAndComments (cssRule);
                   4452:   if (!strncasecmp (cssRule, "auto", 4))
1.184     vatton   4453:     page.typed_data.value = PageAuto;
1.82      cvs      4454:   else if (!strncasecmp (cssRule, "always", 6))
1.59      cvs      4455:     {
1.184     vatton   4456:       page.typed_data.unit = UNIT_REL;
                   4457:       page.typed_data.value = PageAlways;
1.59      cvs      4458:     }
1.82      cvs      4459:   else if (!strncasecmp (cssRule, "avoid", 5))
1.59      cvs      4460:     {
1.184     vatton   4461:       page.typed_data.unit = UNIT_REL;
                   4462:       page.typed_data.value = PageAvoid;
1.59      cvs      4463:     }
1.82      cvs      4464:   else if (!strncasecmp (cssRule, "left", 4))
1.59      cvs      4465:     {
1.184     vatton   4466:       page.typed_data.unit = UNIT_REL;
                   4467:       page.typed_data.value = PageLeft;
1.59      cvs      4468:     }
1.82      cvs      4469:   else if (!strncasecmp (cssRule, "right", 5))
1.59      cvs      4470:     {
1.184     vatton   4471:       page.typed_data.unit = UNIT_REL;
                   4472:       page.typed_data.value = PageRight;
1.59      cvs      4473:     }
1.82      cvs      4474:   else if (!strncasecmp (cssRule, "inherit", 7))
1.59      cvs      4475:     {
1.293     quint    4476:       page.typed_data.unit = VALUE_INHERIT;
1.184     vatton   4477:       page.typed_data.value = PageInherit;
1.59      cvs      4478:     }
                   4479:   cssRule = SkipWord (cssRule);
1.295     vatton   4480:   /* check if it's an important rule */
                   4481:   cssRule = CheckImportantRule (cssRule, ctxt);
1.59      cvs      4482:   /* install the new presentation */
1.295     vatton   4483:   if (DoApply &&
                   4484:       (page.typed_data.unit == UNIT_REL ||
                   4485:        page.typed_data.unit == VALUE_INHERIT))
                   4486:     /* TtaSetStylePresentation (PRPageAfter, element, tsch, ctxt, page) */;
1.59      cvs      4487:   return (cssRule);
                   4488: }
                   4489: 
                   4490: /*----------------------------------------------------------------------
1.60      cvs      4491:  ParseCSSPageBreakInside: parse a CSS page-break-inside attribute 
1.59      cvs      4492:   ----------------------------------------------------------------------*/
1.79      cvs      4493: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
1.207     vatton   4494:                                      PresentationContext ctxt,
1.79      cvs      4495:                                      char *cssRule, CSSInfoPtr css,
                   4496:                                      ThotBool isHTML)
1.59      cvs      4497: {
                   4498:   PresentationValue   page;
                   4499: 
1.184     vatton   4500:   page.typed_data.unit = UNIT_INVALID;
1.59      cvs      4501:   page.typed_data.real = FALSE;
1.82      cvs      4502:   cssRule = SkipBlanksAndComments (cssRule);
                   4503:   if (!strncasecmp (cssRule, "auto", 4))
1.59      cvs      4504:     {
1.184     vatton   4505:       /*page.typed_data.unit = UNIT_REL;*/
                   4506:       page.typed_data.value = PageAuto;
1.59      cvs      4507:     }
1.82      cvs      4508:   else if (!strncasecmp (cssRule, "avoid", 5))
1.59      cvs      4509:     {
1.184     vatton   4510:       page.typed_data.unit = UNIT_REL;
                   4511:       page.typed_data.value = PageAvoid;
1.59      cvs      4512:     }
1.82      cvs      4513:   else if (!strncasecmp (cssRule, "inherit", 7))
1.59      cvs      4514:     {
1.293     quint    4515:       /* page.typed_data.unit = VALUE_INHERIT; */
1.184     vatton   4516:       page.typed_data.value = PageInherit;
1.59      cvs      4517:     }
                   4518:   cssRule = SkipWord (cssRule);
1.295     vatton   4519:   cssRule = CheckImportantRule (cssRule, ctxt);
1.59      cvs      4520:   /* install the new presentation */
1.293     quint    4521:   /*if ((page.typed_data.unit == UNIT_REL ||
                   4522:     page.typed_data.unit == VALUE_INHERIT) &&
1.184     vatton   4523:     page.typed_data.value == PageAvoid && DoApply)
1.295     vatton   4524:     TtaSetStylePresentation (PRPageInside, element, tsch, ctxt, page);*/
1.59      cvs      4525:   return (cssRule);
                   4526: }
1.18      cvs      4527: 
1.60      cvs      4528: /*----------------------------------------------------------------------
1.217     vatton   4529:    ParseSVGStrokeWidth: parse a SVG stroke-width property value.
1.60      cvs      4530:   ----------------------------------------------------------------------*/
1.79      cvs      4531: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
1.207     vatton   4532:                                  PresentationContext ctxt, char *cssRule,
1.79      cvs      4533:                                  CSSInfoPtr css, ThotBool isHTML)
1.60      cvs      4534: {
                   4535:   PresentationValue   width;
                   4536:   
1.82      cvs      4537:   cssRule = SkipBlanksAndComments (cssRule);
1.60      cvs      4538:   width.typed_data.value = 0;
1.184     vatton   4539:   width.typed_data.unit = UNIT_INVALID;
1.60      cvs      4540:   width.typed_data.real = FALSE;
1.110     vatton   4541:   if (isdigit (*cssRule) || *cssRule == '.')
1.166     vatton   4542:     {
1.60      cvs      4543:      cssRule = ParseCSSUnit (cssRule, &width);
1.184     vatton   4544:      if (width.typed_data.unit == UNIT_BOX)
                   4545:        width.typed_data.unit = UNIT_PX;
1.166     vatton   4546:     }
1.295     vatton   4547:   else
                   4548:     cssRule = SkipValue ("Invalid stroke-width value", cssRule);
                   4549: 
                   4550:   /* check if it's an important rule */
                   4551:   cssRule = CheckImportantRule (cssRule, ctxt);
1.184     vatton   4552:   if (width.typed_data.unit != UNIT_INVALID && DoApply)
1.117     vatton   4553:     {
1.207     vatton   4554:       TtaSetStylePresentation (PRLineWeight, element, tsch, ctxt, width);
1.117     vatton   4555:       width.typed_data.value = 1;
1.184     vatton   4556:       width.typed_data.unit = UNIT_REL;
1.117     vatton   4557:     }
1.60      cvs      4558:   return (cssRule);
                   4559: }
                   4560: 
1.217     vatton   4561: /*----------------------------------------------------------------------
                   4562:    ParseCSSPosition: parse a CSS Position attribute string.
                   4563:   ----------------------------------------------------------------------*/
                   4564: static char *ParseCSSPosition (Element element, PSchema tsch,
1.305     quint    4565:                               PresentationContext ctxt, char *cssRule,
                   4566:                               CSSInfoPtr css, ThotBool isHTML)
1.217     vatton   4567: {
1.305     quint    4568:   char               *ptr;
                   4569:   PresentationValue   pval;
1.217     vatton   4570: 
1.305     quint    4571:   pval.typed_data.value = 0;
                   4572:   pval.typed_data.unit = UNIT_BOX;
                   4573:   pval.typed_data.real = FALSE;
1.217     vatton   4574:   cssRule = SkipBlanksAndComments (cssRule);
                   4575:   ptr = cssRule;
                   4576:   if (!strncasecmp (cssRule, "static", 6))
1.305     quint    4577:     pval.typed_data.value = PositionStatic;
1.217     vatton   4578:   else if (!strncasecmp (cssRule, "relative", 7))
1.305     quint    4579:     pval.typed_data.value = PositionRelative;
1.217     vatton   4580:   else if (!strncasecmp (cssRule, "absolute", 8))
1.305     quint    4581:     pval.typed_data.value = PositionAbsolute;
1.217     vatton   4582:   else if (!strncasecmp (cssRule, "fixed", 5))
1.305     quint    4583:     pval.typed_data.value = PositionFixed;
1.217     vatton   4584:   else if (!strncasecmp (cssRule, "inherit", 7))
1.305     quint    4585:     pval.typed_data.unit = VALUE_INHERIT;
                   4586: 
                   4587:   if (pval.typed_data.value == 0 && pval.typed_data.unit != VALUE_INHERIT)
                   4588:     {
                   4589:       cssRule = SkipValue ("Invalid position value", ptr);
                   4590:       cssRule = CheckImportantRule (cssRule, ctxt);
                   4591:       cssRule = SkipValue (NULL, cssRule);
                   4592:     }
1.217     vatton   4593:   else
1.305     quint    4594:     {
                   4595:       cssRule = SkipValue (NULL, cssRule);
                   4596:       cssRule = CheckImportantRule (cssRule, ctxt);
                   4597:       if (DoApply)
                   4598:        TtaSetStylePresentation (PRPosition, element, tsch, ctxt, pval);
                   4599:     }
1.217     vatton   4600:   return (cssRule);
                   4601: }
                   4602: 
                   4603: /*----------------------------------------------------------------------
                   4604:    ParseCSSTop: parse a CSS Top attribute
                   4605:   ----------------------------------------------------------------------*/
                   4606: static char *ParseCSSTop (Element element, PSchema tsch,
                   4607:                           PresentationContext context, char *cssRule,
                   4608:                           CSSInfoPtr css, ThotBool isHTML)
                   4609: {
                   4610:   PresentationValue   val;
                   4611:   char               *ptr;
                   4612: 
                   4613:   cssRule = SkipBlanksAndComments (cssRule);
                   4614:   ptr = cssRule;
1.305     quint    4615:   /* first parse the value */
                   4616:   if (!strncasecmp (cssRule, "auto", 4))
1.217     vatton   4617:     {
                   4618:       val.typed_data.unit = VALUE_AUTO;
                   4619:       val.typed_data.value = 0;
                   4620:       val.typed_data.real = FALSE;
                   4621:       cssRule = SkipWord (cssRule);
                   4622:     }
1.305     quint    4623:   else if (!strncasecmp (cssRule, "inherit", 7))
                   4624:     {
                   4625:       val.typed_data.unit = VALUE_INHERIT;
                   4626:       cssRule = SkipWord (cssRule);
                   4627:     }
1.217     vatton   4628:   else
                   4629:     cssRule = ParseCSSUnit (cssRule, &val);
                   4630:   if (val.typed_data.value != 0 &&
                   4631:       (val.typed_data.unit == UNIT_INVALID ||
                   4632:        val.typed_data.unit == UNIT_BOX))
                   4633:     {
1.218     vatton   4634:       cssRule = SkipValue ("top value", ptr);
1.217     vatton   4635:       val.typed_data.unit = UNIT_PX;
                   4636:     }
1.295     vatton   4637:   cssRule = CheckImportantRule (cssRule, context);
1.217     vatton   4638:   if (DoApply)
1.305     quint    4639:     TtaSetStylePresentation (PRTop, element, tsch, context, val);
1.217     vatton   4640:   return (cssRule);
                   4641: }
                   4642: 
                   4643: /*----------------------------------------------------------------------
                   4644:    ParseCSSRight: parse a CSS Right attribute
                   4645:   ----------------------------------------------------------------------*/
                   4646: static char *ParseCSSRight (Element element, PSchema tsch,
                   4647:                           PresentationContext context, char *cssRule,
                   4648:                           CSSInfoPtr css, ThotBool isHTML)
                   4649: {
                   4650:   PresentationValue   val;
                   4651:   char               *ptr;
                   4652: 
                   4653:   cssRule = SkipBlanksAndComments (cssRule);
                   4654:   ptr = cssRule;
                   4655:   /* first parse the attribute string */
1.305     quint    4656:   if (!strncasecmp (cssRule, "auto", 4))
1.217     vatton   4657:     {
                   4658:       val.typed_data.unit = VALUE_AUTO;
                   4659:       val.typed_data.value = 0;
                   4660:       val.typed_data.real = FALSE;
                   4661:       cssRule = SkipWord (cssRule);
                   4662:     }
1.305     quint    4663:   else if (!strncasecmp (cssRule, "inherit", 7))
                   4664:     {
                   4665:       val.typed_data.unit = VALUE_INHERIT;
                   4666:       cssRule = SkipWord (cssRule);
                   4667:     }
1.217     vatton   4668:   else
                   4669:     cssRule = ParseCSSUnit (cssRule, &val);
                   4670:   if (val.typed_data.value != 0 &&
                   4671:       (val.typed_data.unit == UNIT_INVALID ||
                   4672:        val.typed_data.unit == UNIT_BOX))
                   4673:     {
1.218     vatton   4674:       cssRule = SkipValue ("right value", ptr);
1.217     vatton   4675:       val.typed_data.unit = UNIT_PX;
                   4676:     }
1.295     vatton   4677:   cssRule = CheckImportantRule (cssRule, context);
1.217     vatton   4678:   if (DoApply)
1.305     quint    4679:     TtaSetStylePresentation (PRRight, element, tsch, context, val);
1.217     vatton   4680:   return (cssRule);
                   4681: }
                   4682: 
                   4683: /*----------------------------------------------------------------------
                   4684:    ParseCSSBottom: parse a CSS Bottom attribute
                   4685:   ----------------------------------------------------------------------*/
                   4686: static char *ParseCSSBottom (Element element, PSchema tsch,
                   4687:                           PresentationContext context, char *cssRule,
                   4688:                           CSSInfoPtr css, ThotBool isHTML)
                   4689: {
                   4690:   PresentationValue   val;
                   4691:   char               *ptr;
                   4692: 
                   4693:   cssRule = SkipBlanksAndComments (cssRule);
                   4694:   ptr = cssRule;
                   4695:   /* first parse the attribute string */
1.305     quint    4696:   if (!strncasecmp (cssRule, "auto", 4))
1.217     vatton   4697:     {
                   4698:       val.typed_data.unit = VALUE_AUTO;
                   4699:       val.typed_data.value = 0;
                   4700:       val.typed_data.real = FALSE;
                   4701:       cssRule = SkipWord (cssRule);
                   4702:     }
1.305     quint    4703:   else if (!strncasecmp (cssRule, "inherit", 7))
                   4704:     {
                   4705:       val.typed_data.unit = VALUE_INHERIT;
                   4706:       cssRule = SkipWord (cssRule);
                   4707:     }
1.217     vatton   4708:   else
                   4709:     cssRule = ParseCSSUnit (cssRule, &val);
                   4710:   if (val.typed_data.value != 0 &&
                   4711:       (val.typed_data.unit == UNIT_INVALID ||
                   4712:        val.typed_data.unit == UNIT_BOX))
                   4713:     {
1.218     vatton   4714:       cssRule = SkipValue ("bottom value", ptr);
1.217     vatton   4715:       val.typed_data.unit = UNIT_PX;
                   4716:     }
1.295     vatton   4717:   cssRule = CheckImportantRule (cssRule, context);
1.217     vatton   4718:   if (DoApply)
1.305     quint    4719:     TtaSetStylePresentation (PRBottom, element, tsch, context, val);
1.217     vatton   4720:   return (cssRule);
                   4721: }
                   4722: 
                   4723: /*----------------------------------------------------------------------
                   4724:    ParseCSSLeft: parse a CSS Left attribute
                   4725:   ----------------------------------------------------------------------*/
                   4726: static char *ParseCSSLeft (Element element, PSchema tsch,
                   4727:                           PresentationContext context, char *cssRule,
                   4728:                           CSSInfoPtr css, ThotBool isHTML)
                   4729: {
                   4730:   PresentationValue   val;
                   4731:   char               *ptr;
                   4732: 
                   4733:   cssRule = SkipBlanksAndComments (cssRule);
                   4734:   ptr = cssRule;
                   4735:   /* first parse the attribute string */
1.305     quint    4736:   if (!strncasecmp (cssRule, "auto", 4))
1.217     vatton   4737:     {
                   4738:       val.typed_data.unit = VALUE_AUTO;
                   4739:       val.typed_data.value = 0;
                   4740:       val.typed_data.real = FALSE;
                   4741:       cssRule = SkipWord (cssRule);
                   4742:     }
1.305     quint    4743:   else if (!strncasecmp (cssRule, "inherit", 7))
                   4744:     {
                   4745:       val.typed_data.unit = VALUE_INHERIT;
                   4746:       cssRule = SkipWord (cssRule);
                   4747:     }
1.217     vatton   4748:   else
                   4749:     cssRule = ParseCSSUnit (cssRule, &val);
                   4750:   if (val.typed_data.value != 0 &&
                   4751:       (val.typed_data.unit == UNIT_INVALID ||
                   4752:        val.typed_data.unit == UNIT_BOX))
                   4753:     {
1.218     vatton   4754:       cssRule = SkipValue ("left value", ptr);
1.217     vatton   4755:       val.typed_data.unit = UNIT_PX;
                   4756:     }
1.295     vatton   4757:   cssRule = CheckImportantRule (cssRule, context);
1.217     vatton   4758:   if (DoApply)
1.305     quint    4759:     TtaSetStylePresentation (PRLeft, element, tsch, context, val);
1.217     vatton   4760:   return (cssRule);
                   4761: }
                   4762: 
                   4763: /*----------------------------------------------------------------------
                   4764:    ParseCSSZIndex: parse a CSS z-index attribute
                   4765:   ----------------------------------------------------------------------*/
                   4766: static char *ParseCSSZIndex (Element element, PSchema tsch,
                   4767:                             PresentationContext context, char *cssRule,
                   4768:                             CSSInfoPtr css, ThotBool isHTML)
                   4769: {
                   4770:   PresentationValue   val;
                   4771:   char               *ptr;
                   4772: 
                   4773:   cssRule = SkipBlanksAndComments (cssRule);
                   4774:   ptr = cssRule;
                   4775:   /* first parse the attribute string */
                   4776:   if (!strncasecmp (cssRule, "auto", 4) ||
                   4777:       !strncasecmp (cssRule, "inherit", 7))
                   4778:     {
                   4779:       val.typed_data.unit = VALUE_AUTO;
                   4780:       val.typed_data.value = 0;
                   4781:       val.typed_data.real = FALSE;
                   4782:       cssRule = SkipWord (cssRule);
                   4783:     }
                   4784:   else
                   4785:     {
                   4786:       cssRule = ParseCSSUnit (cssRule, &val);
                   4787:       if (val.typed_data.unit != UNIT_BOX)
                   4788:        {
1.218     vatton   4789:          cssRule = SkipValue ("z-index value", ptr);
1.217     vatton   4790:          val.typed_data.unit = UNIT_BOX;
                   4791:        }
                   4792:     }
1.295     vatton   4793:   cssRule = CheckImportantRule (cssRule, context);
1.217     vatton   4794:   /***
                   4795:   if (DoApply)
1.295     vatton   4796:     TtaSetStylePresentation (PR, element, tsch, context, val);
1.217     vatton   4797:   ***/
                   4798:   return (cssRule);
                   4799: }
                   4800: 
1.18      cvs      4801: /************************************************************************
                   4802:  *                                                                     *  
                   4803:  *     FUNCTIONS STYLE DECLARATIONS                                    *
                   4804:  *                                                                     *  
                   4805:  ************************************************************************/
                   4806: /*
1.59      cvs      4807:  * NOTE: Long attribute name MUST be placed before shortened ones !
1.18      cvs      4808:  *        e.g. "FONT-SIZE" must be placed before "FONT"
                   4809:  */
                   4810: static CSSProperty CSSProperties[] =
                   4811: {
1.82      cvs      4812:    {"background-color", ParseCSSBackgroundColor},
                   4813:    {"background-image", ParseCSSBackgroundImage},
                   4814:    {"background-repeat", ParseCSSBackgroundRepeat},
                   4815:    {"background-attachment", ParseCSSBackgroundAttachment},
                   4816:    {"background-position", ParseCSSBackgroundPosition},
                   4817:    {"background", ParseCSSBackground},
                   4818:    {"border-top-width", ParseCSSBorderTopWidth},
                   4819:    {"border-right-width", ParseCSSBorderRightWidth},
                   4820:    {"border-bottom-width", ParseCSSBorderBottomWidth},
                   4821:    {"border-left-width", ParseCSSBorderLeftWidth},
                   4822:    {"border-width", ParseCSSBorderWidth},
                   4823:    {"border-top-color", ParseCSSBorderColorTop},
                   4824:    {"border-right-color", ParseCSSBorderColorRight},
                   4825:    {"border-bottom-color", ParseCSSBorderColorBottom},
                   4826:    {"border-left-color", ParseCSSBorderColorLeft},
                   4827:    {"border-color", ParseCSSBorderColor},
                   4828:    {"border-top-style", ParseCSSBorderStyleTop},
                   4829:    {"border-right-style", ParseCSSBorderStyleRight},
                   4830:    {"border-bottom-style", ParseCSSBorderStyleBottom},
                   4831:    {"border-left-style", ParseCSSBorderStyleLeft},
                   4832:    {"border-style", ParseCSSBorderStyle},
                   4833:    {"border-top", ParseCSSBorderTop},
                   4834:    {"border-right", ParseCSSBorderRight},
                   4835:    {"border-bottom", ParseCSSBorderBottom},
                   4836:    {"border-left", ParseCSSBorderLeft},
                   4837:    {"border", ParseCSSBorder},
1.234     vatton   4838:    {"bottom", ParseCSSBottom},
1.82      cvs      4839:    {"clear", ParseCSSClear},
1.234     vatton   4840:    {"color", ParseCSSForeground},
1.184     vatton   4841:    {"content", ParseCSSContent},
1.234     vatton   4842:    {"direction", ParseCSSDirection},
1.82      cvs      4843:    {"display", ParseCSSDisplay},
1.234     vatton   4844:    {"float", ParseCSSFloat},
                   4845:    {"font-family", ParseCSSFontFamily},
                   4846:    {"font-style", ParseCSSFontStyle},
                   4847:    {"font-variant", ParseCSSFontVariant},
                   4848:    {"font-weight", ParseCSSFontWeight},
                   4849:    {"font-size-adjust", ParseCSSFontSizeAdjust},
                   4850:    {"font-size", ParseCSSFontSize},
                   4851:    {"font", ParseCSSFont},
                   4852:    {"height", ParseCSSHeight},
1.217     vatton   4853:    {"left", ParseCSSLeft},
1.234     vatton   4854:    {"letter-spacing", ParseCSSLetterSpacing},
                   4855:    {"line-height", ParseCSSLineHeight},
1.82      cvs      4856:    {"list-style-type", ParseCSSListStyleType},
                   4857:    {"list-style-image", ParseCSSListStyleImage},
                   4858:    {"list-style-position", ParseCSSListStylePosition},
                   4859:    {"list-style", ParseCSSListStyle},
1.234     vatton   4860:    {"margin-bottom", ParseCSSMarginBottom},
                   4861:    {"margin-top", ParseCSSMarginTop},
                   4862:    {"margin-right", ParseCSSMarginRight},
                   4863:    {"margin-left", ParseCSSMarginLeft},
                   4864:    {"margin", ParseCSSMargin},
                   4865:    {"padding-top", ParseCSSPaddingTop},
                   4866:    {"padding-right", ParseCSSPaddingRight},
                   4867:    {"padding-bottom", ParseCSSPaddingBottom},
                   4868:    {"padding-left", ParseCSSPaddingLeft},
                   4869:    {"padding", ParseCSSPadding},
1.82      cvs      4870:    {"page-break-before", ParseCSSPageBreakBefore},
                   4871:    {"page-break-after", ParseCSSPageBreakAfter},
                   4872:    {"page-break-inside", ParseCSSPageBreakInside},
1.234     vatton   4873:    {"position", ParseCSSPosition},
                   4874:    {"right", ParseCSSRight},
                   4875:    {"text-align", ParseCSSTextAlign},
1.243     quint    4876:    {"text-anchor", ParseCSSTextAnchor},
1.234     vatton   4877:    {"text-indent", ParseCSSTextIndent},
                   4878:    {"text-decoration", ParseCSSTextDecoration},
                   4879:    {"text-transform", ParseCSSTextTransform},
                   4880:    {"top", ParseCSSTop},
                   4881:    {"unicode-bidi", ParseCSSUnicodeBidi},
                   4882:    {"vertical-align", ParseCSSVerticalAlign},
                   4883:    {"white-space", ParseCSSWhiteSpace},
                   4884:    {"width", ParseCSSWidth},
                   4885:    {"word-spacing", ParseCSSWordSpacing},
                   4886:    {"z-index", ParseCSSZIndex},
1.60      cvs      4887: 
                   4888:    /* SVG extensions */
1.234     vatton   4889:    {"fill-opacity", ParseSVGFillOpacity},
                   4890:    {"fill", ParseSVGFill},
                   4891:    {"opacity", ParseSVGOpacity},
1.170     cheyroul 4892:    {"stroke-opacity", ParseSVGStrokeOpacity},
1.82      cvs      4893:    {"stroke-width", ParseSVGStrokeWidth},
1.234     vatton   4894:    {"stroke", ParseSVGStroke}
1.18      cvs      4895: };
1.155     cheyroul 4896: 
1.18      cvs      4897: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
                   4898: 
                   4899: /*----------------------------------------------------------------------
1.59      cvs      4900:    ParseCSSRule: parse a CSS Style string                        
1.306     quint    4901:    we expect the input string describing the style to be of the form
                   4902:      property: value [ ; property: value ]* 
1.18      cvs      4903:    but tolerate incorrect or incomplete input                    
                   4904:   ----------------------------------------------------------------------*/
1.79      cvs      4905: static void  ParseCSSRule (Element element, PSchema tsch,
1.207     vatton   4906:                           PresentationContext ctxt, char *cssRule,
1.79      cvs      4907:                           CSSInfoPtr css, ThotBool isHTML)
1.18      cvs      4908: {
1.34      cvs      4909:   DisplayMode         dispMode;
1.250     vatton   4910:   char               *p = NULL, *next;
1.214     quint    4911:   char               *valueStart;
1.18      cvs      4912:   int                 lg;
1.34      cvs      4913:   unsigned int        i;
1.76      cvs      4914:   ThotBool            found;
1.18      cvs      4915: 
1.34      cvs      4916:   /* avoid too many redisplay */
1.207     vatton   4917:   dispMode = TtaGetDisplayMode (ctxt->doc);
1.34      cvs      4918:   if (dispMode == DisplayImmediately)
1.207     vatton   4919:     TtaSetDisplayMode (ctxt->doc, DeferredDisplay);
1.34      cvs      4920: 
1.82      cvs      4921:   while (*cssRule != EOS)
1.18      cvs      4922:     {
1.82      cvs      4923:       cssRule = SkipBlanksAndComments (cssRule);
1.153     vatton   4924:       if (*cssRule < 0x41 || *cssRule > 0x7A ||
1.133     vatton   4925:          (*cssRule > 0x5A && *cssRule < 0x60))
1.153     vatton   4926:        cssRule++;
1.194     vatton   4927:       else if (*cssRule != EOS)
1.89      cvs      4928:        {
1.153     vatton   4929:          found = FALSE;
                   4930:          /* look for the type of property */
                   4931:          for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
1.18      cvs      4932:            {
1.153     vatton   4933:              lg = strlen (CSSProperties[i].name);
                   4934:              if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
                   4935:                {
                   4936:                  p = cssRule + lg;
                   4937:                  found = TRUE;
                   4938:                  i--;
                   4939:                }
1.18      cvs      4940:            }
1.153     vatton   4941:          if (i == NB_CSSSTYLEATTRIBUTE)
1.234     vatton   4942:            cssRule = SkipProperty (cssRule, TRUE);
1.153     vatton   4943:          else
1.18      cvs      4944:            {
1.153     vatton   4945:              /* update index and skip the ":" indicator if present */
1.86      cvs      4946:              p = SkipBlanksAndComments (p);
1.153     vatton   4947:              if (*p == ':')
1.61      cvs      4948:                {
1.153     vatton   4949:                  p++;
                   4950:                  p = SkipBlanksAndComments (p);
                   4951:                  /* try to parse the value associated with this property */
                   4952:                  if (CSSProperties[i].parsing_function != NULL)
                   4953:                    {
1.214     quint    4954:                      valueStart = p;
                   4955:                      p = CSSProperties[i].parsing_function (element, tsch,
                   4956:                                                         ctxt, p, css, isHTML);
                   4957:                      if (!element && isHTML)
                   4958:                        {
                   4959:                          if  (ctxt->type == HTML_EL_Input)
                   4960:                            /* it's a generic rule for the HTML element input.
                   4961:                               Generate a Thot Pres rule for each kind of
                   4962:                               input element */
                   4963:                            {
                   4964:                              ctxt->type = HTML_EL_Text_Input;
                   4965:                              p = CSSProperties[i].parsing_function (element,
                   4966:                                          tsch, ctxt, valueStart, css, isHTML);
                   4967:                              ctxt->type = HTML_EL_Password_Input;
                   4968:                              p = CSSProperties[i].parsing_function (element,
                   4969:                                          tsch, ctxt, valueStart, css, isHTML);
                   4970:                              ctxt->type = HTML_EL_File_Input;
                   4971:                              p = CSSProperties[i].parsing_function (element,
                   4972:                                          tsch, ctxt, valueStart, css, isHTML);
                   4973:                              ctxt->type = HTML_EL_Checkbox_Input;
                   4974:                              p = CSSProperties[i].parsing_function (element,
                   4975:                                          tsch, ctxt, valueStart, css, isHTML);
                   4976:                              ctxt->type = HTML_EL_Radio_Input;
                   4977:                              p = CSSProperties[i].parsing_function (element,
                   4978:                                          tsch, ctxt, valueStart, css, isHTML);
                   4979:                              ctxt->type = HTML_EL_Submit_Input;
                   4980:                              p = CSSProperties[i].parsing_function (element,
                   4981:                                          tsch, ctxt, valueStart, css, isHTML);
                   4982:                              ctxt->type = HTML_EL_Reset_Input;
                   4983:                              p = CSSProperties[i].parsing_function (element,
                   4984:                                          tsch, ctxt, valueStart, css, isHTML);
                   4985:                              ctxt->type = HTML_EL_Button_Input;
                   4986:                              p = CSSProperties[i].parsing_function (element,
                   4987:                                          tsch, ctxt, valueStart, css, isHTML);
                   4988:                              ctxt->type = HTML_EL_Input;
                   4989:                            }
                   4990:                          else if (ctxt->type == HTML_EL_ruby)
                   4991:                            /* it's a generic rule for the HTML element ruby.
                   4992:                               Generate a Thot Pres rule for each kind of
                   4993:                               ruby element. */
                   4994:                            {
                   4995:                              ctxt->type = HTML_EL_simple_ruby;
                   4996:                              p = CSSProperties[i].parsing_function (element,
                   4997:                                          tsch, ctxt, valueStart, css, isHTML);
                   4998:                              ctxt->type = HTML_EL_complex_ruby;
                   4999:                              p = CSSProperties[i].parsing_function (element,
                   5000:                                          tsch, ctxt, valueStart, css, isHTML);
                   5001:                              ctxt->type = HTML_EL_ruby;
                   5002:                            }
                   5003:                        }
1.153     vatton   5004:                      /* update index and skip the ";" separator if present */
1.250     vatton   5005:                      next = SkipBlanksAndComments (p);
                   5006:                      if (*next != EOS && *next != ';')
1.251     vatton   5007:                        CSSParseError ("Missing closing ';'", cssRule, p);
1.250     vatton   5008:                      cssRule = next;
1.153     vatton   5009:                    }
1.61      cvs      5010:                }
1.153     vatton   5011:              else
1.234     vatton   5012:                cssRule = SkipProperty (cssRule, TRUE);
1.18      cvs      5013:            }
                   5014:        }
                   5015:       /* next property */
1.82      cvs      5016:       cssRule = SkipBlanksAndComments (cssRule);
1.89      cvs      5017:       if (*cssRule == '}')
                   5018:        {
                   5019:          cssRule++;
1.168     vatton   5020:          CSSPrintError ("Invalid character", "}");
1.89      cvs      5021:          cssRule = SkipBlanksAndComments (cssRule);
                   5022:        }
1.155     cheyroul 5023:       if (*cssRule == ',' ||
                   5024:          *cssRule == ';')
1.18      cvs      5025:        {
                   5026:          cssRule++;
1.82      cvs      5027:          cssRule = SkipBlanksAndComments (cssRule);
1.18      cvs      5028:        }
                   5029:     }
1.34      cvs      5030: 
                   5031:   /* restore the display mode */
                   5032:   if (dispMode == DisplayImmediately)
1.207     vatton   5033:     TtaSetDisplayMode (ctxt->doc, dispMode);
1.18      cvs      5034: }
1.1       cvs      5035: 
1.111     cvs      5036: /*----------------------------------------------------------------------
1.59      cvs      5037:    ParseHTMLSpecificStyle: parse and apply a CSS Style string.
1.18      cvs      5038:    This function must be called when a specific style is applied to an
                   5039:    element.
1.114     quint    5040:    The parameter specificity is the specificity of the style, 0 if it is
                   5041:    not really a CSS rule.
1.1       cvs      5042:   ----------------------------------------------------------------------*/
1.79      cvs      5043: void  ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.114     quint    5044:                              int specificity, ThotBool destroy)
1.1       cvs      5045: {
1.257     vatton   5046:   DisplayMode         dispMode;
1.207     vatton   5047:   PresentationContext ctxt;
                   5048:   ElementType         elType;
                   5049:   ThotBool            isHTML;
1.1       cvs      5050: 
1.207     vatton   5051:   /*  A rule applying to BODY is really meant to address HTML */
                   5052:   elType = TtaGetElementType (el);
1.286     quint    5053:   NewLineSkipped = 0;
1.207     vatton   5054:   /* store the current line for eventually reported errors */
                   5055:   LineNumber = TtaGetElementLineNumber (el);
                   5056:   if (destroy)
                   5057:     /* no reported errors */
                   5058:     ParsedDoc = 0;
                   5059:   else if (ParsedDoc != doc)
                   5060:     {
                   5061:       /* update the context for reported errors */
                   5062:       ParsedDoc = doc;
                   5063:       DocURL = DocumentURLs[doc];
                   5064:     }
                   5065:   isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
                   5066:   /* create the context of the Specific presentation driver */
                   5067:   ctxt = TtaGetSpecificStyleContext (doc);
                   5068:   if (ctxt == NULL)
                   5069:     return;
                   5070:   ctxt->type = elType.ElTypeNum;
                   5071:   ctxt->cssSpecificity = specificity;
1.236     quint    5072:   ctxt->cssLine = LineNumber;
1.207     vatton   5073:   ctxt->destroy = destroy;
                   5074:   /* first use of the context */
                   5075:   ctxt->uses = 1;
1.257     vatton   5076:   /* save the current display mode */
                   5077:   dispMode = TtaGetDisplayMode (doc);
1.207     vatton   5078:   /* Call the parser */
                   5079:   ParseCSSRule (el, NULL, (PresentationContext) ctxt, cssRule, NULL, isHTML);
1.257     vatton   5080:   /* restore the display mode if necessary */
                   5081:   TtaSetDisplayMode (doc, dispMode);
1.207     vatton   5082:   /* check if the context can be freed */
                   5083:   ctxt->uses -= 1;
                   5084:   if (ctxt->uses == 0)
                   5085:     /* no image loading */
                   5086:     TtaFreeMemory(ctxt);
1.1       cvs      5087: }
                   5088: 
1.68      cvs      5089: 
1.1       cvs      5090: /*----------------------------------------------------------------------
1.207     vatton   5091:   ParseGenericSelector: Create a generic context for a given selector
                   5092:   string.
                   5093:   If the selector is made of multiple comma, it parses them one at a time
                   5094:   and return the end of the selector string to be handled or NULL.
1.231     vatton   5095:   The parameter ctxt gives the current style context which will be passed
                   5096:   to Thotlib.
                   5097:   The parameter css points to the current CSS context.
                   5098:   The parameter link points to the link element.
                   5099:   The parameter url gives the URL of the parsed style sheet.
1.1       cvs      5100:   ----------------------------------------------------------------------*/
1.207     vatton   5101: static char *ParseGenericSelector (char *selector, char *cssRule,
1.79      cvs      5102:                                   GenericContext ctxt, Document doc,
1.231     vatton   5103:                                   CSSInfoPtr css, Element link, char *url)
1.79      cvs      5104: {
                   5105:   ElementType        elType;
                   5106:   PSchema            tsch;
1.119     vatton   5107:   AttributeType      attrType;
1.240     quint    5108:   char              *deb, *cur, *sel, *next, c;
1.118     vatton   5109:   char              *schemaName, *mappedName;
1.79      cvs      5110:   char              *names[MAX_ANCESTORS];
                   5111:   char              *ids[MAX_ANCESTORS];
                   5112:   char              *classes[MAX_ANCESTORS];
                   5113:   char              *pseudoclasses[MAX_ANCESTORS];
                   5114:   char              *attrs[MAX_ANCESTORS];
                   5115:   char              *attrvals[MAX_ANCESTORS];
1.133     vatton   5116:   AttrMatch          attrmatch[MAX_ANCESTORS];
1.255     vatton   5117:   ElemRel            rel[MAX_ANCESTORS];
1.91      cvs      5118:   int                i, j, k, max;
1.256     vatton   5119:   int                att, kind;
1.118     vatton   5120:   int                specificity, xmlType;
1.217     vatton   5121:   int                skippedNL;
1.306     quint    5122:   PresentationValue  pval;
1.79      cvs      5123:   ThotBool           isHTML;
1.183     vatton   5124:   ThotBool           level, quoted;
1.1       cvs      5125: 
1.207     vatton   5126:   sel = ctxt->sel;
1.82      cvs      5127:   sel[0] = EOS;
1.117     vatton   5128:   specificity = 0;
1.1       cvs      5129:   for (i = 0; i < MAX_ANCESTORS; i++)
                   5130:     {
1.25      cvs      5131:       names[i] = NULL;
                   5132:       ids[i] = NULL;
                   5133:       classes[i] = NULL;
                   5134:       pseudoclasses[i] = NULL;
                   5135:       attrs[i] = NULL;
                   5136:       attrvals[i] = NULL;
1.133     vatton   5137:       attrmatch[i] = Txtmatch;
1.255     vatton   5138:       rel[i] = RelAncestor;
1.25      cvs      5139:       ctxt->name[i] = 0;
                   5140:       ctxt->names_nb[i] = 0;
                   5141:       ctxt->attrType[i] = 0;
1.129     vatton   5142:       ctxt->attrLevel[i] = 0;
1.25      cvs      5143:       ctxt->attrText[i] = NULL;
1.178     quint    5144:       ctxt->attrMatch[i] = Txtmatch;
1.1       cvs      5145:     }
1.25      cvs      5146:   ctxt->box = 0;
1.306     quint    5147:   ctxt->pseudo = PbNone;
1.25      cvs      5148:   ctxt->type = 0;
1.114     quint    5149:   /* the specificity of the rule depends on the selector */
                   5150:   ctxt->cssSpecificity = 0;
1.231     vatton   5151:   /* localisation of the CSS rule */
                   5152:   ctxt->cssLine = LineNumber + NewLineSkipped;
                   5153:   ctxt->cssURL = url;
1.240     quint    5154: 
1.286     quint    5155:   skippedNL = NewLineSkipped;
1.82      cvs      5156:   selector = SkipBlanksAndComments (selector);
1.286     quint    5157:   NewLineSkipped = skippedNL;
1.27      cvs      5158:   cur = &sel[0];
1.25      cvs      5159:   max = 0; /* number of loops */
1.1       cvs      5160:   while (1)
                   5161:     {
1.85      cvs      5162:       /* point to the following word in sel[] */
1.27      cvs      5163:       deb = cur;
1.25      cvs      5164:       /* copy an item of the selector into sel[] */
1.1       cvs      5165:       /* put one word in the sel buffer */
1.82      cvs      5166:       while (*selector != EOS && *selector != ',' &&
                   5167:              *selector != '.' && *selector != ':' &&
1.118     vatton   5168:              *selector != '#' && *selector != '[' &&
1.250     vatton   5169:              *selector != '>' && *selector != '+' &&
1.118     vatton   5170:             !TtaIsBlank (selector))
1.50      cvs      5171:             *cur++ = *selector++;
1.82      cvs      5172:       *cur++ = EOS; /* close the first string  in sel[] */
                   5173:       if (deb[0] != EOS)
1.117     vatton   5174:        {
1.240     quint    5175:          if (deb[0] <= 64 && deb[0] != '*')
                   5176:            {
                   5177:              CSSPrintError ("Invalid element", deb);
                   5178:              return NULL;
                   5179:            }
1.149     vatton   5180:          else
1.240     quint    5181:            {
                   5182:              names[0] = deb;
                   5183:              if (!strcmp (names[0], "html"))
                   5184:                /* give a greater priority to the backgoud color of html */
                   5185:                specificity += 3;
                   5186:              else
                   5187:                /* selector "*" has specificity zero */
                   5188:                if (strcmp (names[0], "*"))
                   5189:                  specificity += 1;
                   5190:            }
1.117     vatton   5191:        }
1.25      cvs      5192:       else
1.27      cvs      5193:        names[0] = NULL;
1.226     quint    5194: 
1.27      cvs      5195:       classes[0] = NULL;
                   5196:       pseudoclasses[0] = NULL;
                   5197:       ids[0] = NULL;
                   5198:       attrs[0] = NULL;
                   5199:       attrvals[0] = NULL;
1.267     vatton   5200:       attrmatch[0] = Txtmatch;
1.25      cvs      5201: 
1.27      cvs      5202:       /* now names[0] points to the beginning of the parsed item
1.25      cvs      5203:         and cur to the next chain to be parsed */
1.129     vatton   5204:       while (*selector == '.' || *selector == ':' ||
1.234     vatton   5205:             *selector == '#' || *selector == '[')
1.129     vatton   5206:       {
1.85      cvs      5207:        /* point to the following word in sel[] */
                   5208:        deb = cur;
1.129     vatton   5209:        if (*selector == '.')
                   5210:          {
                   5211:            selector++;
                   5212:            while (*selector != EOS && *selector != ',' &&
                   5213:                   *selector != '.' && *selector != ':' &&
                   5214:                   !TtaIsBlank (selector))
1.240     quint    5215:              {
                   5216:                if (*selector == '\\')
                   5217:                  {
                   5218:                    selector++;
                   5219:                    if (*selector != EOS)
                   5220:                      *cur++ = *selector++;
                   5221:                  }
                   5222:                else
                   5223:                  *cur++ = *selector++;
                   5224:              }
1.129     vatton   5225:            /* close the word */
                   5226:            *cur++ = EOS;
                   5227:            /* point to the class in sel[] if it's valid name */
                   5228:            if (deb[0] <= 64)
                   5229:              {
1.168     vatton   5230:                CSSPrintError ("Invalid class", deb);
1.116     vatton   5231:                DoApply = FALSE;
1.129     vatton   5232:              }
                   5233:            else
                   5234:              {
                   5235:                classes[0] = deb;
1.117     vatton   5236:                specificity += 10;
1.227     quint    5237:                if (names[0] && !strcmp (names[0], "*"))
1.226     quint    5238:                  names[0] = NULL;
1.129     vatton   5239:              }
                   5240:          }
                   5241:        else if (*selector == ':')
                   5242:          {
                   5243:            selector++;
                   5244:            while (*selector != EOS && *selector != ',' &&
                   5245:                   *selector != '.' && *selector != ':' &&
                   5246:                   !TtaIsBlank (selector))
                   5247:              *cur++ = *selector++;
                   5248:            /* close the word */
                   5249:            *cur++ = EOS;
1.306     quint    5250:            /* point to the pseudoclass in sel[] if it's a valid name */
1.129     vatton   5251:            if (deb[0] <= 64)
                   5252:              {
1.168     vatton   5253:                CSSPrintError ("Invalid pseudoclass", deb);
1.129     vatton   5254:                DoApply = FALSE;
                   5255:              }
                   5256:            else
                   5257:              {
                   5258:                if (!strcmp (deb, "first-letter") ||
                   5259:                    !strcmp (deb, "first-line") ||
1.266     quint    5260:                    !strcmp (deb, "hover") ||
                   5261:                    !strcmp (deb, "focus"))
1.129     vatton   5262:                  /* not supported */
1.116     vatton   5263:                  DoApply = FALSE;
1.129     vatton   5264:                else
                   5265:                  specificity += 10;
1.306     quint    5266:                if (!strncmp (deb, "before", 6) || !strncmp (deb, "after", 5))
                   5267:                  pseudoclasses[0] = deb;
                   5268:                else if (!strncmp (deb, "lang", 4))
1.238     quint    5269:                  /* it's the lang pseudo-class */
                   5270:                  {
                   5271:                    if (deb[4] != '(' || deb[strlen(deb)-1] != ')')
                   5272:                      /* at least one paranthesis is missing. Error */
                   5273:                      {
                   5274:                        CSSPrintError ("Invalid :lang pseudoclass", deb);
                   5275:                        DoApply = FALSE;
                   5276:                      }
                   5277:                    else
1.306     quint    5278:                      /* simulate selector [lang|="xxx"] if there is no
1.238     quint    5279:                         attribute yet in the selector */
                   5280:                      if (!attrs[0])
                   5281:                        {
                   5282:                          deb[strlen(deb)-1] = EOS;
                   5283:                          deb[4] = EOS;
                   5284:                          attrmatch[0] = Txtsubstring;
                   5285:                          attrs[0] = deb;
                   5286:                          attrvals[0] = &deb[5];
                   5287:                        }
                   5288:                  }
                   5289:                else
1.267     vatton   5290:                  pseudoclasses[0] = deb;
1.227     quint    5291:                if (names[0] && !strcmp (names[0], "*"))
1.226     quint    5292:                  names[0] = NULL;
1.129     vatton   5293:              }
                   5294:          }
                   5295:        else if (*selector == '#')
                   5296:          {
                   5297:            selector++;
                   5298:            while (*selector != EOS && *selector != ',' &&
                   5299:                   *selector != '.' && *selector != ':' &&
1.237     quint    5300:                   *selector != '#' &&
1.129     vatton   5301:                   !TtaIsBlank (selector))
                   5302:              *cur++ = *selector++;
                   5303:            /* close the word */
                   5304:            *cur++ = EOS;
                   5305:            /* point to the attribute in sel[] if it's valid name */
                   5306:            if (deb[0] <= 64)
                   5307:              {
1.168     vatton   5308:                CSSPrintError ("Invalid id", deb);
1.129     vatton   5309:                DoApply = FALSE;
                   5310:              }
                   5311:            else
                   5312:              {
1.237     quint    5313:                if (ids[0] && strcmp(ids[0], deb))
                   5314:                  {
                   5315:                    CSSPrintError ("Too many ids", deb);
                   5316:                    DoApply = FALSE;
                   5317:                  }               
                   5318:                else
                   5319:                  {
                   5320:                    ids[0] = deb;
                   5321:                    specificity += 100;
                   5322:                    if (names[0] && !strcmp (names[0], "*"))
                   5323:                      names[0] = NULL;
                   5324:                  }
1.129     vatton   5325:              }
                   5326:          }
                   5327:        else if (*selector == '[')
                   5328:          {
1.118     vatton   5329:            selector++;
1.129     vatton   5330:            while (*selector != EOS && *selector != ']' &&
1.131     vatton   5331:                   *selector != '=' && *selector != '~' &&
1.133     vatton   5332:                   *selector != '|' && *selector != '^' &&
                   5333:                   *selector != '!')
1.129     vatton   5334:              *cur++ = *selector++;
1.133     vatton   5335:            /* check matching */
                   5336:            if (*selector == '~')
                   5337:              {
                   5338:                attrmatch[0] = Txtword;
                   5339:                selector++;
                   5340:              }
                   5341:            else if (*selector == '|')
                   5342:              {
                   5343:                attrmatch[0] = Txtsubstring;
                   5344:                selector++;
                   5345:              }
                   5346:            else
                   5347:              attrmatch[0] = Txtmatch;
1.129     vatton   5348:            /* close the word */
                   5349:            *cur++ = EOS;
                   5350:            /* point to the attribute in sel[] if it's valid name */
                   5351:            if (deb[0] <= 64)
                   5352:              {
1.168     vatton   5353:                CSSPrintError ("Invalid attribute", deb);
1.129     vatton   5354:                DoApply = FALSE;
                   5355:              }
                   5356:            else
                   5357:              {
                   5358:                attrs[0] = deb;
                   5359:                specificity += 10;
                   5360:              }
                   5361:            if (*selector == '=')
                   5362:              {
                   5363:                /* look for a value "xxxx" */
                   5364:                selector++;
                   5365:                if (*selector != '"')
1.183     vatton   5366:                  quoted = FALSE;
1.129     vatton   5367:                else
                   5368:                  {
1.183     vatton   5369:                    quoted = TRUE;
1.129     vatton   5370:                    /* we are now parsing the attribute value */
                   5371:                    selector++;
1.183     vatton   5372:                  }
                   5373:                deb = cur;
                   5374:                while ((quoted &&
                   5375:                        (*selector != '"' ||
                   5376:                         (*selector == '"' && selector[-1] == '\\'))) ||
                   5377:                       (!quoted && *selector != ']'))
                   5378:                  {
                   5379:                    if (*selector == EOS)
1.129     vatton   5380:                      {
1.183     vatton   5381:                        CSSPrintError ("Invalid attribute value", deb);
                   5382:                        DoApply = FALSE;
1.129     vatton   5383:                      }
1.183     vatton   5384:                    else
1.129     vatton   5385:                      {
1.228     quint    5386:                        if (attrmatch[0] == Txtword && TtaIsBlank (selector))
                   5387:                          {
                   5388:                            CSSPrintError ("No space allowed here: ", selector);
                   5389:                            DoApply = FALSE;
                   5390:                          }
1.238     quint    5391:                        *cur++ = *selector;
1.129     vatton   5392:                      }
1.228     quint    5393:                    selector++;
1.129     vatton   5394:                  }
1.183     vatton   5395:                /* there is a value */
1.204     quint    5396:                if (quoted && *selector == '"')
1.183     vatton   5397:                  {
                   5398:                    selector++;
                   5399:                    quoted = FALSE;
                   5400:                  }
                   5401:                if (*selector != ']')
                   5402:                  {
                   5403:                    CSSPrintError ("Invalid attribute value", deb);
                   5404:                    DoApply = FALSE;
                   5405:                  }
                   5406:                else
                   5407:                  {
                   5408:                    *cur++ = EOS;
                   5409:                    attrvals[0] = deb;
                   5410:                    selector++;
                   5411:                  }
1.129     vatton   5412:              }
                   5413:            /* end of the attribute */
1.183     vatton   5414:            else if (*selector != ']')
1.129     vatton   5415:              {
1.133     vatton   5416:                selector[1] = EOS;
1.183     vatton   5417:                CSSPrintError ("Invalid attribute", selector);
1.133     vatton   5418:                selector += 2;
1.129     vatton   5419:                DoApply = FALSE;
                   5420:              }
                   5421:            else
1.226     quint    5422:              {
1.129     vatton   5423:              selector++;
1.227     quint    5424:              if (names[0] && !strcmp (names[0], "*"))
1.226     quint    5425:                names[0] = NULL;
                   5426:              }
1.130     vatton   5427:          }
                   5428:        else
                   5429:          {
                   5430:            /* not supported selector */
                   5431:            while (*selector != EOS && *selector != ',' &&
                   5432:                   *selector != '.' && *selector != ':' &&
                   5433:                   !TtaIsBlank (selector))
                   5434:              *cur++ = *selector++;
                   5435:            /* close the word */
                   5436:            *cur++ = EOS;
1.205     quint    5437:            CSSPrintError ("Selector not supported:", deb);
1.130     vatton   5438:            DoApply = FALSE;        
1.129     vatton   5439:          }
                   5440:       }
1.1       cvs      5441: 
1.286     quint    5442:       skippedNL = NewLineSkipped;
1.82      cvs      5443:       selector = SkipBlanksAndComments (selector);
1.286     quint    5444:       NewLineSkipped = skippedNL;
                   5445: 
1.25      cvs      5446:       /* is it a multi-level selector? */
1.82      cvs      5447:       if (*selector == EOS)
1.1       cvs      5448:        /* end of the selector */
                   5449:        break;
1.82      cvs      5450:       else if (*selector == ',')
1.1       cvs      5451:        {
                   5452:          /* end of the current selector */
                   5453:          selector++;
1.286     quint    5454:          skippedNL = NewLineSkipped;
1.240     quint    5455:          next = SkipBlanksAndComments (selector);
1.286     quint    5456:          NewLineSkipped = skippedNL;
1.240     quint    5457:          if (*next == EOS)
                   5458:            /* nothing after the comma. Invalid selector */
                   5459:            {
1.308   ! vatton   5460:              /*CSSPrintError ("Syntax error:", selector);*/
1.240     quint    5461:              return NULL;
                   5462:            }
1.1       cvs      5463:          break;
                   5464:        }
1.25      cvs      5465:       else
                   5466:        {
1.143     vatton   5467:          if (*selector == '>')
                   5468:            {
                   5469:              /* handle immediat parent as a simple parent */
                   5470:              selector++;
1.286     quint    5471:              skippedNL = NewLineSkipped;
1.143     vatton   5472:              selector = SkipBlanksAndComments (selector);
1.286     quint    5473:              NewLineSkipped = skippedNL;
1.255     vatton   5474:              rel[0] = RelImmediat;
1.250     vatton   5475:            }
                   5476:          else if (*selector == '+')
                   5477:            {
                   5478:              /* handle immediat parent as a simple parent */
                   5479:              selector++;
1.286     quint    5480:              skippedNL = NewLineSkipped;
1.250     vatton   5481:              selector = SkipBlanksAndComments (selector);
1.286     quint    5482:              NewLineSkipped = skippedNL;
1.255     vatton   5483:              rel[0] = RelPrevious;
1.143     vatton   5484:            }
1.25      cvs      5485:          /* shifts the list to make room for the new name */
                   5486:          max++; /* a new level in ancestor tables */
                   5487:          if (max == MAX_ANCESTORS)
                   5488:            /* abort the CSS parsing */
                   5489:            return (selector);
                   5490:          for (i = max; i > 0; i--)
                   5491:            {
                   5492:              names[i] = names[i - 1];
                   5493:              ids[i] = ids[i - 1];
                   5494:              classes[i] = classes[i - 1];
1.133     vatton   5495:              pseudoclasses[i] = pseudoclasses[i - 1];
1.25      cvs      5496:              attrs[i] = attrs[i - 1];
                   5497:              attrvals[i] = attrvals[i - 1];
1.133     vatton   5498:              attrmatch[i] = attrmatch[i - 1];
1.250     vatton   5499:              rel[i] = rel[i - 1];
1.25      cvs      5500:            }
                   5501:        }
1.1       cvs      5502:     }
                   5503: 
                   5504:   /* Now set up the context block */
1.25      cvs      5505:   i = 0;
                   5506:   k = 0;
                   5507:   j = 0;
1.91      cvs      5508:   /* default schema name */
1.119     vatton   5509:   ctxt->schema = NULL;
1.122     vatton   5510:   elType.ElSSchema = NULL;
                   5511:   schemaName = TtaGetSSchemaName(TtaGetDocumentSSchema (doc));
1.119     vatton   5512:   if (!strcmp (schemaName, "HTML"))
                   5513:     xmlType = XHTML_TYPE;
                   5514:   else if (!strcmp (schemaName, "MathML"))
                   5515:     xmlType = MATH_TYPE;
                   5516:   else if (!strcmp (schemaName, "SVG"))
                   5517:     xmlType = SVG_TYPE;
                   5518:   else if (!strcmp (schemaName, "XLink"))
                   5519:     xmlType = XLINK_TYPE;
                   5520:   else if (!strcmp (schemaName, "Annot"))
                   5521:     xmlType = ANNOT_TYPE;
                   5522:   else
                   5523:     xmlType = XML_TYPE;
1.256     vatton   5524:   while (i <= max && j < MAX_ANCESTORS)
1.25      cvs      5525:     {
                   5526:       if (names[i])
                   5527:        {
1.118     vatton   5528:          /* get the element type of this name in the current document */
1.220     quint    5529:          if (xmlType == XML_TYPE)
1.223     quint    5530:            /* it's a generic XML document. Check the main document schema */
1.220     quint    5531:            {
                   5532:              elType.ElSSchema = TtaGetDocumentSSchema (doc);
                   5533:              TtaGetXmlElementType (names[i], &elType, &mappedName, doc);
                   5534:              if (!elType.ElTypeNum)
1.226     quint    5535:                {
                   5536:                  if (!strcmp (names[i], "*"))
                   5537:                    elType.ElTypeNum = HTML_EL_ANY_TYPE;
                   5538:                  else
                   5539:                    elType.ElSSchema = NULL;
                   5540:                }
1.220     quint    5541:            }
                   5542:          else
1.226     quint    5543:            {
                   5544:              if (!strcmp (names[i], "*"))
                   5545:                {
                   5546:                  elType.ElSSchema = TtaGetDocumentSSchema (doc);
                   5547:                  elType.ElTypeNum = HTML_EL_ANY_TYPE;
                   5548:                }
                   5549:              else
                   5550:                MapXMLElementType (xmlType, names[i], &elType, &mappedName, &c,
                   5551:                                   &level, doc);
                   5552:            }
1.25      cvs      5553:          if (i == 0)
                   5554:            {
1.106     cvs      5555:              if (elType.ElSSchema == NULL)
                   5556:                {
1.269     vatton   5557:                  /* Selector not found: Search in the list of loaded schemas */
1.106     cvs      5558:                  TtaGetXmlElementType (names[i], &elType, NULL, doc);
1.119     vatton   5559:                  if (elType.ElSSchema)
                   5560:                    {
1.154     vatton   5561:                      /* the element type concerns an imported nature */
1.119     vatton   5562:                      schemaName = TtaGetSSchemaName(elType.ElSSchema);
                   5563:                      if (!strcmp (schemaName, "HTML"))
1.269     vatton   5564:                        {
                   5565:                          if (xmlType == XHTML_TYPE &&
                   5566:                              DocumentMeta[doc] && DocumentMeta[doc]->xmlformat)
                   5567:                            /* the selector was found but the case is not correct */
                   5568:                            elType.ElSSchema = NULL;
                   5569:                          else
                   5570:                            xmlType = XHTML_TYPE;
                   5571:                        }
1.119     vatton   5572:                      else if (!strcmp (schemaName, "MathML"))
                   5573:                        xmlType = MATH_TYPE;
                   5574:                      else if (!strcmp (schemaName, "SVG"))
                   5575:                        xmlType = SVG_TYPE;
                   5576:                      else if (!strcmp (schemaName, "XLink"))
                   5577:                        xmlType = XLINK_TYPE;
                   5578:                      else if (!strcmp (schemaName, "Annot"))
                   5579:                        xmlType = ANNOT_TYPE;
                   5580:                      else
                   5581:                        xmlType = XML_TYPE;
                   5582:                    }
1.118     vatton   5583: #ifdef XML_GENERIC
1.119     vatton   5584:                  else if (xmlType == XML_TYPE)
1.106     cvs      5585:                    {
                   5586:                      /* Creation of a new element type in the main schema */
                   5587:                      elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.118     vatton   5588:                      TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
1.106     cvs      5589:                    }
1.118     vatton   5590: #endif /* XML_GENERIC */
1.122     vatton   5591:                  else
                   5592:                    {
                   5593:                      if (xmlType != XHTML_TYPE)
                   5594:                        {
                   5595:                          MapXMLElementType (XHTML_TYPE, names[i], &elType,
                   5596:                                             &mappedName, &c, &level, doc);
                   5597:                          if (elType.ElSSchema)
1.123     vatton   5598:                            elType.ElSSchema = GetXHTMLSSchema (doc);
1.122     vatton   5599:                        }
                   5600:                      if (elType.ElSSchema == NULL && xmlType != MATH_TYPE)
                   5601:                        {
                   5602:                          MapXMLElementType (MATH_TYPE, names[i], &elType,
                   5603:                                             &mappedName, &c, &level, doc);
                   5604:                          if (elType.ElSSchema)
1.123     vatton   5605:                            elType.ElSSchema = GetMathMLSSchema (doc);
1.122     vatton   5606:                        }
                   5607:                      if (elType.ElSSchema == NULL && xmlType != SVG_TYPE)
                   5608:                        {
                   5609:                          MapXMLElementType (SVG_TYPE, names[i], &elType,
                   5610:                                             &mappedName, &c, &level, doc);
                   5611:                          if (elType.ElSSchema)
1.123     vatton   5612:                            elType.ElSSchema = GetSVGSSchema (doc);
1.122     vatton   5613:                        }
                   5614:                    }
1.118     vatton   5615:                }
1.119     vatton   5616: 
1.118     vatton   5617:              if (elType.ElSSchema == NULL)
                   5618:                /* cannot apply these CSS rules */
                   5619:                DoApply = FALSE;
                   5620:              else
                   5621:                {
                   5622:                  /* Store the element type */
                   5623:                  ctxt->type = elType.ElTypeNum;
                   5624:                  ctxt->name[0] = elType.ElTypeNum;
                   5625:                  ctxt->names_nb[0] = 0;
1.255     vatton   5626:                  ctxt->rel[0] = RelAncestor;
1.118     vatton   5627:                  ctxt->schema = elType.ElSSchema;
1.106     cvs      5628:                }
1.25      cvs      5629:            }
                   5630:          else if (elType.ElTypeNum != 0)
                   5631:            {
                   5632:              /* look at the current context to see if the type is already
                   5633:                 stored */
1.121     vatton   5634:              j = 1;
1.250     vatton   5635:              while (j < k &&
1.255     vatton   5636:                     (ctxt->name[j] != elType.ElTypeNum ||
                   5637:                      ctxt->rel[j] != RelAncestor))
1.25      cvs      5638:                j++;
                   5639:              if (j == k)
                   5640:                {
                   5641:                  ctxt->name[j] = elType.ElTypeNum;
                   5642:                  if (j != 0)
1.255     vatton   5643:                    {
                   5644:                      ctxt->names_nb[j] = 1;
                   5645:                      ctxt->rel[j] = rel[i];
                   5646:                    }
1.25      cvs      5647:                }
                   5648:              else
                   5649:                /* increment the number of ancestor levels */
                   5650:                ctxt->names_nb[j]++;
                   5651:            }
1.154     vatton   5652: #ifdef XML_GENERIC
                   5653:          else if (xmlType == XML_TYPE)
                   5654:            {
1.158     vatton   5655:              TtaGetXmlElementType (names[i], &elType, NULL, doc);
                   5656:              if (elType.ElTypeNum == 0)
                   5657:                {
                   5658:                  /* Creation of a new element type in the main schema */
                   5659:                  elType.ElSSchema = TtaGetDocumentSSchema (doc);
                   5660:                  TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
                   5661:                }
1.154     vatton   5662:              if (elType.ElTypeNum != 0)
                   5663:                {
                   5664:                  /* look at the current context to see if the type is already
                   5665:                     stored */
                   5666:                  j = 1;
1.250     vatton   5667:                  while (j < k &&
1.255     vatton   5668:                         (ctxt->name[j] != elType.ElTypeNum ||
                   5669:                          ctxt->rel[j] != RelAncestor))
1.154     vatton   5670:                    j++;
                   5671:                  if (j == k)
                   5672:                    {
                   5673:                      ctxt->name[j] = elType.ElTypeNum;
                   5674:                      if (j != 0)
1.250     vatton   5675:                        {
                   5676:                          ctxt->names_nb[j] = 1;
                   5677:                          ctxt->rel[j] = rel[i];
                   5678:                        }
                   5679:                      else
1.255     vatton   5680:                        ctxt->rel[j] = RelAncestor;
1.154     vatton   5681:                    }
                   5682:                  else
                   5683:                    /* increment the number of ancestor levels */
                   5684:                    ctxt->names_nb[j]++;
                   5685:                }
                   5686:            }
                   5687: #endif /* XML_GENERIC */
1.25      cvs      5688:          else
1.117     vatton   5689:            j = k;
1.25      cvs      5690:        }
1.117     vatton   5691:       else
                   5692:        j = k;
1.1       cvs      5693: 
1.25      cvs      5694:       /* store attributes information */
                   5695:       if (classes[i])
                   5696:        {
                   5697:          ctxt->attrText[j] = classes[i];
1.119     vatton   5698:          if (xmlType == SVG_TYPE)
1.100     vatton   5699:            ctxt->attrType[j] = SVG_ATTR_class;
1.119     vatton   5700:          else if (xmlType == MATH_TYPE)
1.91      cvs      5701:            ctxt->attrType[j] = MathML_ATTR_class;
1.119     vatton   5702:          else if (xmlType == XHTML_TYPE)
1.107     cvs      5703:            ctxt->attrType[j] = HTML_ATTR_Class;
                   5704:          else
1.119     vatton   5705: #ifdef XML_GENERIC
1.107     cvs      5706:            ctxt->attrType[j] = XML_ATTR_class;
                   5707: #else /* XML_GENERIC */
1.91      cvs      5708:            ctxt->attrType[j] = HTML_ATTR_Class;
1.107     cvs      5709: #endif /* XML_GENERIC */
1.267     vatton   5710:            /* a "class" attribute on an element may contain several
                   5711:               words, one for each class it matches */
                   5712:          ctxt->attrMatch[j] = Txtword;
1.79      cvs      5713:          /* add a new entry */
1.129     vatton   5714:          /* update attrLevel */
                   5715:          ctxt->attrLevel[j] = i;
                   5716:          j++;
1.25      cvs      5717:        }
1.79      cvs      5718:       if (pseudoclasses[i])
1.25      cvs      5719:        {
                   5720:          ctxt->attrText[j] = pseudoclasses[i];
1.306     quint    5721:          if (!strncmp (deb, "before", 6))
                   5722:            ctxt->pseudo = PbBefore;
                   5723:          else if (!strncmp (deb, "after", 5))
                   5724:            ctxt->pseudo = PbAfter;
1.107     cvs      5725:          else
1.306     quint    5726:            {
                   5727:              if (xmlType == SVG_TYPE)
                   5728:                ctxt->attrType[j] = SVG_ATTR_PseudoClass;
                   5729:              else if (xmlType == MATH_TYPE)
                   5730:                ctxt->attrType[j] = MathML_ATTR_PseudoClass;
                   5731:              else if (xmlType == XHTML_TYPE)
                   5732:                ctxt->attrType[j] = HTML_ATTR_PseudoClass;
                   5733:              else
1.119     vatton   5734: #ifdef XML_GENERIC
1.306     quint    5735:                ctxt->attrType[j] = XML_ATTR_PseudoClass;
1.107     cvs      5736: #else /* XML_GENERIC */
1.306     quint    5737:                ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.107     cvs      5738: #endif /* XML_GENERIC */
1.306     quint    5739:              ctxt->attrMatch[j] = Txtmatch;
                   5740:            }
1.79      cvs      5741:          /* add a new entry */
1.129     vatton   5742:          /* update attrLevel */
                   5743:          ctxt->attrLevel[j] = i;
                   5744:          j++;
1.25      cvs      5745:        }
1.79      cvs      5746:       if (ids[i])
1.25      cvs      5747:        {
                   5748:          ctxt->attrText[j] = ids[i];
1.119     vatton   5749:          if (xmlType == SVG_TYPE)
1.100     vatton   5750:            ctxt->attrType[j] = SVG_ATTR_id;
1.119     vatton   5751:          else if (xmlType == MATH_TYPE)
1.91      cvs      5752:            ctxt->attrType[j] = MathML_ATTR_id;
1.119     vatton   5753:          else if (xmlType == XHTML_TYPE)
1.107     cvs      5754:            ctxt->attrType[j] = HTML_ATTR_ID;
                   5755:          else
1.119     vatton   5756: #ifdef XML_GENERIC
1.307     vatton   5757:            ctxt->attrType[j] = XML_ATTR_xmlid;
1.107     cvs      5758: #else /* XML_GENERIC */
1.91      cvs      5759:            ctxt->attrType[j] = HTML_ATTR_ID;
1.107     cvs      5760: #endif /* XML_GENERIC */
1.267     vatton   5761:          ctxt->attrMatch[j] = Txtmatch;
1.80      cvs      5762:          /* add a new entry */
1.129     vatton   5763:          /* update attrLevel */
                   5764:          ctxt->attrLevel[j] = i;
                   5765:          j++;
1.25      cvs      5766:        }
1.79      cvs      5767:       if (attrs[i])
1.25      cvs      5768:        {
1.125     vatton   5769:          /* it's an attribute */
1.220     quint    5770:          if (xmlType == XML_TYPE)
                   5771:            {
                   5772:              attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
                   5773:              TtaGetXmlAttributeType (attrs[i], &attrType, doc);
                   5774:              att = attrType.AttrTypeNum;
                   5775:            }
                   5776:          else
1.221     vatton   5777:            {
                   5778:              MapXMLAttribute (xmlType, attrs[i], names[i], &level, doc, &att);
                   5779:              if (ctxt->schema == NULL && att != 0)
                   5780:                ctxt->schema = TtaGetDocumentSSchema (doc);
                   5781:            }
1.278     quint    5782:          if (att == 0)
                   5783:            /* Attribute name not found: Search in the list of all loaded
                   5784:               schemas */
                   5785:            {
                   5786:              attrType.AttrSSchema = NULL;
                   5787:              TtaGetXmlAttributeType (attrs[i], &attrType, doc);
                   5788:              att = attrType.AttrTypeNum;
                   5789:            }
1.127     quint    5790:          if (att == DummyAttribute && !strcmp (schemaName, "HTML"))
                   5791:            /* it's the "type" attribute for an "input" element. In the tree
                   5792:               it's represented by the element type, not by an attribute */
                   5793:            att = 0;
1.119     vatton   5794:          ctxt->attrType[j] = att;
1.133     vatton   5795:          ctxt->attrMatch[j] = attrmatch[i];
1.125     vatton   5796:          attrType.AttrSSchema = ctxt->schema;
                   5797:          attrType.AttrTypeNum = att;
1.119     vatton   5798:          if (i == 0 && att == 0 && ctxt->schema == NULL)
                   5799:            {
1.125     vatton   5800:              /* Not found -> search in the list of loaded schemas */
1.119     vatton   5801:              attrType.AttrSSchema = NULL;
                   5802:              TtaGetXmlAttributeType (attrs[i], &attrType, doc);
                   5803:              ctxt->attrType[j] = attrType.AttrTypeNum;
                   5804:              if (attrType.AttrSSchema)
1.125     vatton   5805:                /* the element type concerns an imported nature */
                   5806:                schemaName = TtaGetSSchemaName(attrType.AttrSSchema);
1.119     vatton   5807: #ifdef XML_GENERIC
                   5808:              else if (xmlType == XML_TYPE)
                   5809:                {
                   5810:                  /* The attribute is not yet present in the tree */
                   5811:                  /* Create a new global attribute */
                   5812:                  attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
                   5813:                  TtaAppendXmlAttribute (attrs[i], &attrType, doc);
                   5814:                }
                   5815: #endif /* XML_GENERIC */
                   5816: 
                   5817:              if (attrType.AttrSSchema == NULL)
                   5818:                /* cannot apply these CSS rules */
                   5819:                DoApply = FALSE;
1.136     quint    5820:              else if (elType.ElSSchema)
                   5821:                ctxt->schema = elType.ElSSchema;
1.119     vatton   5822:              else
1.136     quint    5823:                ctxt->schema = attrType.AttrSSchema;
1.119     vatton   5824:            }
1.125     vatton   5825:          /* check the attribute type */
                   5826:          if (!strcmp (schemaName, "HTML"))
                   5827:            xmlType = XHTML_TYPE;
                   5828:          else if (!strcmp (schemaName, "MathML"))
                   5829:            xmlType = MATH_TYPE;
                   5830:          else if (!strcmp (schemaName, "SVG"))
                   5831:            xmlType = SVG_TYPE;
                   5832:          else if (!strcmp (schemaName, "XLink"))
                   5833:            xmlType = XLINK_TYPE;
                   5834:          else if (!strcmp (schemaName, "Annot"))
                   5835:            xmlType = ANNOT_TYPE;
                   5836:          else
                   5837:            xmlType = XML_TYPE;
                   5838:          kind = TtaGetAttributeKind (attrType);
1.220     quint    5839:          if (kind == 0 && attrvals[i])
1.125     vatton   5840:            {
                   5841:              /* enumerated value */
1.248     gully    5842:              MapXMLAttributeValue (xmlType, attrvals[i], &attrType, &kind);
1.125     vatton   5843:              /* store the attribute value */
                   5844:              ctxt->attrText[j] = (char *) kind;
                   5845:            }
                   5846:          else
                   5847:            ctxt->attrText[j] = attrvals[i];
1.129     vatton   5848:          /* update attrLevel */
                   5849:          ctxt->attrLevel[j] = i;
                   5850:          j++;
1.25      cvs      5851:        }
                   5852:       i++;
1.117     vatton   5853:       /* add a new entry */
                   5854:       k++;
1.129     vatton   5855:       if (k < j)
                   5856:        k = j;
1.119     vatton   5857:       if (i == 1 && ctxt->schema == NULL)
                   5858:        /* use the document schema */
                   5859:        ctxt->schema = TtaGetDocumentSSchema (doc);
1.1       cvs      5860:     }
1.117     vatton   5861:   /* set the selector specificity */
                   5862:   ctxt->cssSpecificity = specificity;
1.25      cvs      5863:   /* Get the schema name of the main element */
1.119     vatton   5864:   schemaName = TtaGetSSchemaName (ctxt->schema);
                   5865:   isHTML = (strcmp (schemaName, "HTML") == 0);
1.206     vatton   5866:   tsch = GetPExtension (doc, ctxt->schema, css, link);
1.306     quint    5867: 
                   5868:   if (tsch && ctxt->pseudo != PbNone && DoApply)
                   5869:     /* there is a pseudo element :before or :after. Generate a function rule
                   5870:        CreateFirst or CreateLast */
                   5871:     {
                   5872:       pval.typed_data.unit = UNIT_REL;
                   5873:       pval.typed_data.real = FALSE;
                   5874:       pval.typed_data.value = (int) ctxt->pseudo;
                   5875:       if (ctxt->pseudo == PbBefore)
                   5876:        TtaSetStylePresentation (PRCreateFirst, NULL, tsch,
                   5877:                                 (PresentationContext) ctxt, pval);
                   5878:       else if (ctxt->pseudo == PbAfter)
                   5879:        TtaSetStylePresentation (PRCreateLast, NULL, tsch,
                   5880:                                 (PresentationContext) ctxt, pval);
                   5881:     }
1.217     vatton   5882:   skippedNL = NewLineSkipped;
1.119     vatton   5883:   if (tsch && cssRule)
                   5884:     ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
1.116     vatton   5885:   /* future CSS rules should apply */
                   5886:   DoApply = TRUE;
1.217     vatton   5887:   if (selector)
                   5888:     NewLineSkipped = skippedNL;
1.1       cvs      5889:   return (selector);
                   5890: }
                   5891: 
                   5892: /*----------------------------------------------------------------------
1.206     vatton   5893:   ParseStyleDeclaration: parse a style declaration stored in the style
                   5894:   element of a document                       
                   5895:   We expect the style string to be of the form:                   
                   5896:   .pinky, .awful { color: pink; font-family: helvetica }        
1.231     vatton   5897:   The parameter css points to the current CSS context.
                   5898:   The parameter link points to the link element.
                   5899:   The parameter url gives the URL of the parsed style sheet.
1.1       cvs      5900:   ----------------------------------------------------------------------*/
1.206     vatton   5901: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
1.231     vatton   5902:                                   CSSInfoPtr css, Element link, char *url,
                   5903:                                   ThotBool destroy)
1.1       cvs      5904: {
1.79      cvs      5905:   GenericContext      ctxt;
                   5906:   char               *decl_end;
                   5907:   char               *sel_end;
                   5908:   char               *selector;
1.1       cvs      5909: 
                   5910:   /* separate the selectors string */
1.82      cvs      5911:   cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      5912:   decl_end = cssRule;
1.82      cvs      5913:   while (*decl_end != EOS && *decl_end != '{')
1.286     quint    5914:     {
                   5915:       if (*decl_end == EOL)
                   5916:        NewLineSkipped++;
                   5917:       decl_end++;
                   5918:     }
1.82      cvs      5919:   if (*decl_end == EOS)
1.86      cvs      5920:     {
1.168     vatton   5921:       CSSPrintError ("Invalid selector", cssRule);
1.86      cvs      5922:       return;
                   5923:     }
1.1       cvs      5924:   /* verify and clean the selector string */
                   5925:   sel_end = decl_end - 1;
1.82      cvs      5926:   while (*sel_end == SPACE || *sel_end == BSPACE ||
                   5927:         *sel_end == EOL || *sel_end == CR)
1.1       cvs      5928:     sel_end--;
                   5929:   sel_end++;
1.82      cvs      5930:   *sel_end = EOS;
1.1       cvs      5931:   selector = cssRule;
                   5932: 
                   5933:   /* now, deal with the content ... */
                   5934:   decl_end++;
                   5935:   cssRule = decl_end;
1.137     vatton   5936:   decl_end = &cssRule[strlen (cssRule) - 1];
                   5937:   if (*decl_end != '{')
                   5938:     *decl_end = EOS;
1.1       cvs      5939:   /*
                   5940:    * parse the style attribute string and install the corresponding
                   5941:    * presentation attributes on the new element
                   5942:    */
                   5943:   ctxt = TtaGetGenericStyleContext (doc);
                   5944:   if (ctxt == NULL)
                   5945:     return;
                   5946:   ctxt->destroy = destroy;
1.207     vatton   5947:   /* first use of the context */
                   5948:   ctxt->uses = 1;
1.197     vatton   5949:   while (selector && *selector != EOS)
1.231     vatton   5950:     selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css,
                   5951:                                     link, url);
1.207     vatton   5952:   /* check if the context can be freed */
                   5953:   ctxt->uses -= 1;
                   5954:   if (ctxt->uses == 0)
                   5955:     /* no image loading */
                   5956:     TtaFreeMemory (ctxt);
1.1       cvs      5957: }
                   5958: 
                   5959: /************************************************************************
                   5960:  *                                                                     *  
                   5961:  *     EVALUATION FUNCTIONS / CASCADING AND OVERLOADING                *
                   5962:  *                                                                     *  
                   5963:  ************************************************************************/
                   5964: 
                   5965: /*----------------------------------------------------------------------
1.59      cvs      5966:    IsImplicitClassName: return wether the Class name is an        
1.1       cvs      5967:    implicit one, eg "H1" or "H2 EM" meaning it's a GI name       
                   5968:    or an HTML context name.                                      
                   5969:   ----------------------------------------------------------------------*/
1.248     gully    5970: int IsImplicitClassName (char *class_, Document doc)
1.1       cvs      5971: {
1.79      cvs      5972:    char         name[200];
                   5973:    char        *cur = name;
                   5974:    char        *first; 
                   5975:    char         save;
                   5976:    SSchema      schema;
1.1       cvs      5977: 
                   5978:    /* make a local copy */
1.248     gully    5979:    strncpy (name, class_, 199);
1.1       cvs      5980:    name[199] = 0;
                   5981: 
                   5982:    /* loop looking if each word is a GI */
                   5983:    while (*cur != 0)
                   5984:      {
                   5985:        first = cur;
                   5986:        cur = SkipWord (cur);
                   5987:        save = *cur;
                   5988:        *cur = 0;
                   5989:        schema = NULL;
                   5990:        if (MapGI (first, &schema, doc) == -1)
                   5991:          {
                   5992:             return (0);
                   5993:          }
                   5994:        *cur = save;
1.82      cvs      5995:        cur = SkipBlanksAndComments (cur);
1.1       cvs      5996:      }
                   5997:    return (1);
                   5998: }
                   5999: 
                   6000: /************************************************************************
                   6001:  *                                                                     *  
1.114     quint    6002:  *  Functions needed for support of HTML: translate to CSS equivalent   *
1.1       cvs      6003:  *                                                                     *  
                   6004:  ************************************************************************/
                   6005: 
                   6006: /*----------------------------------------------------------------------
1.59      cvs      6007:    HTMLSetBackgroundColor:
1.1       cvs      6008:   ----------------------------------------------------------------------*/
1.264     vatton   6009: void HTMLSetBackgroundColor (Document doc, Element el, int specificity,
                   6010:                             char *color)
1.1       cvs      6011: {
1.79      cvs      6012:    char             css_command[100];
1.1       cvs      6013: 
1.82      cvs      6014:    sprintf (css_command, "background-color: %s", color);
1.264     vatton   6015:    ParseHTMLSpecificStyle (el, css_command, doc, specificity, FALSE);
1.1       cvs      6016: }
                   6017: 
                   6018: /*----------------------------------------------------------------------
1.59      cvs      6019:    HTMLSetForegroundColor:                                        
1.1       cvs      6020:   ----------------------------------------------------------------------*/
1.264     vatton   6021: void HTMLSetForegroundColor (Document doc, Element el, int specificity,
                   6022:                             char *color)
1.1       cvs      6023: {
1.79      cvs      6024:    char           css_command[100];
1.1       cvs      6025: 
1.82      cvs      6026:    sprintf (css_command, "color: %s", color);
1.264     vatton   6027:    ParseHTMLSpecificStyle (el, css_command, doc, specificity, FALSE);
1.1       cvs      6028: }
                   6029: 
                   6030: /*----------------------------------------------------------------------
1.59      cvs      6031:    HTMLResetBackgroundColor:                                      
1.1       cvs      6032:   ----------------------------------------------------------------------*/
1.97      vatton   6033: void HTMLResetBackgroundColor (Document doc, Element el)
1.1       cvs      6034: {
1.79      cvs      6035:    char           css_command[100];
1.1       cvs      6036: 
1.82      cvs      6037:    sprintf (css_command, "background: red");
1.114     quint    6038:    ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1       cvs      6039: }
                   6040: 
                   6041: /*----------------------------------------------------------------------
1.59      cvs      6042:    HTMLResetBackgroundImage:                                      
1.1       cvs      6043:   ----------------------------------------------------------------------*/
1.97      vatton   6044: void HTMLResetBackgroundImage (Document doc, Element el)
1.1       cvs      6045: {
1.79      cvs      6046:    char           css_command[1000];
1.1       cvs      6047: 
1.82      cvs      6048:    sprintf (css_command, "background-image: url(xx); background-repeat: repeat");
1.114     quint    6049:    ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1       cvs      6050: }
                   6051: 
                   6052: /*----------------------------------------------------------------------
1.59      cvs      6053:    HTMLResetForegroundColor:                                      
1.1       cvs      6054:   ----------------------------------------------------------------------*/
1.97      vatton   6055: void HTMLResetForegroundColor (Document doc, Element el)
1.1       cvs      6056: {
1.79      cvs      6057:    char           css_command[100];
1.1       cvs      6058: 
1.36      cvs      6059:    /* it's not necessary to well know the current color but it must be valid */
1.82      cvs      6060:    sprintf (css_command, "color: red");
1.114     quint    6061:    ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1       cvs      6062: }
                   6063: 
                   6064: /*----------------------------------------------------------------------
1.59      cvs      6065:    HTMLSetAlinkColor:                                             
1.1       cvs      6066:   ----------------------------------------------------------------------*/
1.208     vatton   6067: void HTMLSetAlinkColor (Document doc, Element el, char *color)
1.1       cvs      6068: {
1.79      cvs      6069:    char           css_command[100];
1.1       cvs      6070: 
1.215     quint    6071:    sprintf (css_command, ":link { color: %s }", color);
1.208     vatton   6072:    ApplyCSSRules (el, css_command, doc, FALSE);
1.1       cvs      6073: }
                   6074: 
                   6075: /*----------------------------------------------------------------------
1.59      cvs      6076:    HTMLSetAactiveColor:                                           
1.1       cvs      6077:   ----------------------------------------------------------------------*/
1.208     vatton   6078: void HTMLSetAactiveColor (Document doc, Element el, char *color)
1.1       cvs      6079: {
1.79      cvs      6080:    char           css_command[100];
1.1       cvs      6081: 
1.215     quint    6082:    sprintf (css_command, ":active { color: %s }", color);
1.208     vatton   6083:    ApplyCSSRules (el, css_command, doc, FALSE);
1.1       cvs      6084: }
                   6085: 
                   6086: /*----------------------------------------------------------------------
1.59      cvs      6087:    HTMLSetAvisitedColor:                                          
1.1       cvs      6088:   ----------------------------------------------------------------------*/
1.208     vatton   6089: void HTMLSetAvisitedColor (Document doc, Element el, char *color)
1.1       cvs      6090: {
1.79      cvs      6091:    char           css_command[100];
1.1       cvs      6092: 
1.215     quint    6093:    sprintf (css_command, ":visited { color: %s }", color);
1.208     vatton   6094:    ApplyCSSRules (el, css_command, doc, FALSE);
1.1       cvs      6095: }
                   6096: 
                   6097: /*----------------------------------------------------------------------
1.59      cvs      6098:    HTMLResetAlinkColor:                                           
1.1       cvs      6099:   ----------------------------------------------------------------------*/
1.208     vatton   6100: void HTMLResetAlinkColor (Document doc, Element el)
1.1       cvs      6101: {
1.79      cvs      6102:    char           css_command[100];
1.1       cvs      6103: 
1.215     quint    6104:    sprintf (css_command, ":link { color: red }");
1.208     vatton   6105:    ApplyCSSRules (el, css_command, doc, TRUE);
1.1       cvs      6106: }
                   6107: 
                   6108: /*----------------------------------------------------------------------
1.59      cvs      6109:    HTMLResetAactiveColor:                                                 
1.1       cvs      6110:   ----------------------------------------------------------------------*/
1.208     vatton   6111: void HTMLResetAactiveColor (Document doc, Element el)
1.1       cvs      6112: {
1.79      cvs      6113:    char           css_command[100];
1.1       cvs      6114: 
1.215     quint    6115:    sprintf (css_command, ":active { color: red }");
1.208     vatton   6116:    ApplyCSSRules (el, css_command, doc, TRUE);
1.1       cvs      6117: }
                   6118: 
                   6119: /*----------------------------------------------------------------------
1.59      cvs      6120:    HTMLResetAvisitedColor:                                        
1.1       cvs      6121:   ----------------------------------------------------------------------*/
1.208     vatton   6122: void HTMLResetAvisitedColor (Document doc, Element el)
1.1       cvs      6123: {
1.79      cvs      6124:    char           css_command[100];
1.1       cvs      6125: 
1.215     quint    6126:    sprintf (css_command, ":visited { color: red }");
1.208     vatton   6127:    ApplyCSSRules (el, css_command, doc, TRUE);
1.1       cvs      6128: }
                   6129: 
                   6130: /*----------------------------------------------------------------------
1.206     vatton   6131:   ApplyCSSRules: parse a CSS Style description stored in the header of
                   6132:   a HTML document.
1.1       cvs      6133:   ----------------------------------------------------------------------*/
1.79      cvs      6134: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1       cvs      6135: {
1.206     vatton   6136:   CSSInfoPtr          css;
                   6137:   PInfoPtr            pInfo;
1.207     vatton   6138:   ThotBool            loadcss;
                   6139: 
                   6140:   /* check if we have to load CSS */
                   6141:   TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
                   6142:   if (!loadcss)
                   6143:     return;
1.1       cvs      6144: 
1.206     vatton   6145:   css = SearchCSS (doc, NULL, el, &pInfo);
1.1       cvs      6146:   if (css == NULL)
1.209     vatton   6147:     {
                   6148:       /* create the document css context */
                   6149:       css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, el);
                   6150:       pInfo = css->infos[doc];
                   6151:     }
1.206     vatton   6152:   else if (pInfo == NULL)
                   6153:     /* create the entry into the css context */
                   6154:     pInfo = AddInfoCSS (doc, css, CSS_DOCUMENT_STYLE, CSS_ALL, el);
1.209     vatton   6155:   if (pInfo->PiEnabled)
1.231     vatton   6156:     ParseStyleDeclaration (el, cssRule, doc, css, el, NULL, destroy); 
1.1       cvs      6157: }
                   6158: 
                   6159: /*----------------------------------------------------------------------
1.145     quint    6160:    ReadCSSRules:  is the front-end function called by the document parser
                   6161:    when detecting a <style type="text/css"> indicating it's the
1.1       cvs      6162:    beginning of a CSS fragment or when reading a file .css.
                   6163:   
                   6164:    The CSS parser has to handle <!-- ... --> constructs used to
                   6165:    prevent prehistoric browser from displaying the CSS as a text
                   6166:    content. It will stop on any sequence "<x" where x is different
                   6167:    from ! and will return x as to the caller. Theorically x should
1.145     quint    6168:    be equal to / for the </style> end of style.
1.1       cvs      6169:    The parameter doc gives the document tree that contains CSS information.
                   6170:    The parameter docRef gives the document to which CSS are to be applied.
                   6171:    This function uses the current css context or creates it. It's able
1.23      cvs      6172:    to work on the given buffer or call GetNextChar to read the parsed
1.1       cvs      6173:    file.
1.231     vatton   6174:    The parameter url gives the URL of the parsed style sheet.
                   6175:    The parameter numberOfLinesRead gives the number of lines already
1.86      cvs      6176:    read in the file.
1.231     vatton   6177:    The parameter withUndo indicates whether the changes made in the document
1.145     quint    6178:    structure and content have to be registered in the Undo queue or not.
1.1       cvs      6179:   ----------------------------------------------------------------------*/
1.133     vatton   6180: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer, char *url,
1.144     quint    6181:                   int numberOfLinesRead, ThotBool withUndo,
1.206     vatton   6182:                   Element link)
1.1       cvs      6183: {
1.6       cvs      6184:   DisplayMode         dispMode;
1.206     vatton   6185:   CSSInfoPtr          refcss = NULL;
                   6186:   PInfoPtr            pInfo;
1.271     vatton   6187:   char                c, *screentype;
1.138     vatton   6188:   char               *cssRule, *base, *saveDocURL, *ptr;
1.19      cvs      6189:   int                 index;
1.1       cvs      6190:   int                 CSSindex;
                   6191:   int                 CSScomment;
                   6192:   int                 import;
                   6193:   int                 openRule;
1.93      vatton   6194:   int                 newlines;
1.14      cvs      6195:   ThotBool            HTMLcomment;
1.102     vatton   6196:   ThotBool            toParse, eof, quoted;
1.234     vatton   6197:   ThotBool            ignore, media, page;
                   6198:   ThotBool            noRule, ignoreImport, fontface;
1.1       cvs      6199: 
                   6200:   CSScomment = MAX_CSS_LENGTH;
                   6201:   HTMLcomment = FALSE;
                   6202:   CSSindex = 0;
                   6203:   toParse = FALSE;
                   6204:   noRule = FALSE;
1.234     vatton   6205:   media = FALSE;
1.88      cvs      6206:   ignoreImport = FALSE;
1.234     vatton   6207:   ignore = FALSE;
                   6208:   page = FALSE;
                   6209:   quoted = FALSE;
                   6210:   fontface = FALSE;
1.1       cvs      6211:   eof = FALSE;
                   6212:   openRule = 0;
1.234     vatton   6213:   import = MAX_CSS_LENGTH;
1.82      cvs      6214:   c = SPACE;
1.1       cvs      6215:   index = 0;
1.134     vatton   6216:   base = NULL;
1.271     vatton   6217:   screentype = TtaGetEnvString ("SCREEN_TYPE");
1.93      vatton   6218:   /* number of new lines parsed */
                   6219:   newlines = 0;
1.6       cvs      6220:   /* avoid too many redisplay */
                   6221:   dispMode = TtaGetDisplayMode (docRef);
                   6222:   if (dispMode == DisplayImmediately)
                   6223:     TtaSetDisplayMode (docRef, DeferredDisplay);
1.18      cvs      6224: 
                   6225:   /* look for the CSS context */
                   6226:   if (css == NULL)
1.206     vatton   6227:     css = SearchCSS (docRef, NULL, link, &pInfo);
1.207     vatton   6228:   else
                   6229:     pInfo = css->infos[docRef];
1.18      cvs      6230:   if (css == NULL)
1.206     vatton   6231:     {
                   6232:       css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, link);
                   6233:       pInfo = css->infos[docRef];
                   6234:     }
                   6235:   else if (pInfo == NULL)
                   6236:     pInfo = AddInfoCSS (docRef, css, CSS_DOCUMENT_STYLE, CSS_ALL, link);
1.174     vatton   6237:   /* look for the CSS descriptor that points to the extension schema */
                   6238:   refcss = css;
1.224     vatton   6239:   if (pInfo && pInfo->PiCategory == CSS_IMPORT)
1.173     cvs      6240:     {
1.206     vatton   6241:       while (refcss &&
                   6242:           refcss->infos[docRef] && refcss->infos[docRef]->PiCategory == CSS_IMPORT)
1.174     vatton   6243:        refcss = refcss->NextCSS;
1.206     vatton   6244:       if (refcss)
                   6245:        pInfo = refcss->infos[docRef];
1.173     cvs      6246:     }
                   6247: 
1.144     quint    6248:   /* register parsed CSS file and the document to which CSS are to be applied*/
1.86      cvs      6249:   ParsedDoc = docRef;
1.133     vatton   6250:   if (url)
                   6251:     DocURL = url;
1.86      cvs      6252:   else
                   6253:     /* the CSS source in within the document itself */
                   6254:     DocURL = DocumentURLs[docRef];
                   6255:   LineNumber = numberOfLinesRead + 1;
1.93      vatton   6256:   NewLineSkipped = 0;
1.217     vatton   6257:   newlines = 0;
1.82      cvs      6258:   while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
                   6259:     {
                   6260:       c = buffer[index++];
                   6261:       eof = (c == EOS);
                   6262:       CSSbuffer[CSSindex] = c;
1.234     vatton   6263:       if (CSScomment == MAX_CSS_LENGTH ||
1.246     vatton   6264:               c == '*' || c == '/' || c == '<' || c == EOL)
1.82      cvs      6265:        {
                   6266:          /* we're not within a comment or we're parsing * or / */
                   6267:          switch (c)
                   6268:            {
                   6269:            case '@': /* perhaps an import primitive */
1.234     vatton   6270:              if (!fontface && !page && !quoted)
1.135     vatton   6271:                import = CSSindex;
1.82      cvs      6272:              break;
                   6273:            case ';':
1.135     vatton   6274:              if (!quoted && !media && import != MAX_CSS_LENGTH)
1.82      cvs      6275:                { 
                   6276:                  if (strncasecmp (&CSSbuffer[import+1], "import", 6))
                   6277:                    /* it's not an import */
                   6278:                    import = MAX_CSS_LENGTH;
                   6279:                  /* save the text */
                   6280:                  noRule = TRUE;
                   6281:                }
                   6282:              break;
                   6283:            case '*':
1.135     vatton   6284:              if (!quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.82      cvs      6285:                  CSSbuffer[CSSindex - 1] == '/')
                   6286:                /* start a comment */
                   6287:                CSScomment = CSSindex - 1;
                   6288:              break;
                   6289:            case '/':
1.135     vatton   6290:              if (!quoted && CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
1.82      cvs      6291:                  CSSbuffer[CSSindex - 1] == '*')
                   6292:                {
1.234     vatton   6293:                  /* close a comment and ignore its contents */
1.82      cvs      6294:                  CSSindex = CSScomment - 1; /* will be incremented later */
                   6295:                  CSScomment = MAX_CSS_LENGTH;
1.93      vatton   6296:                  /* clean up the buffer */
1.103     vatton   6297:                  if (newlines && CSSindex > 0)
                   6298:                    while (CSSindex > 0 &&
                   6299:                           (CSSbuffer[CSSindex] == SPACE ||
                   6300:                            CSSbuffer[CSSindex] == BSPACE ||
                   6301:                            CSSbuffer[CSSindex] == EOL ||
                   6302:                            CSSbuffer[CSSindex] == TAB ||
                   6303:                            CSSbuffer[CSSindex] == __CR__))
1.93      vatton   6304:                      {
                   6305:                        if ( CSSbuffer[CSSindex] == EOL)
                   6306:                          {
                   6307:                            LineNumber ++;
1.217     vatton   6308:                              newlines --;
1.93      vatton   6309:                          }
                   6310:                      CSSindex--;
                   6311:                      }
1.82      cvs      6312:                }
1.234     vatton   6313:              else if (!fontface && !page && !quoted &&
                   6314:                       CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.82      cvs      6315:                       CSSbuffer[CSSindex - 1] ==  '<')
                   6316:                {
                   6317:                  /* this is the closing tag ! */
                   6318:                  CSSindex -= 2; /* remove </ from the CSS string */
                   6319:                  noRule = TRUE;
                   6320:                } 
                   6321:              break;
                   6322:            case '<':
1.234     vatton   6323:              if (!fontface && !page && !quoted &&
                   6324:                  CSScomment == MAX_CSS_LENGTH)
1.82      cvs      6325:                {
                   6326:                  /* only if we're not parsing a comment */
                   6327:                  c = buffer[index++];
                   6328:                  eof = (c == EOS);
                   6329:                  if (c == '!')
                   6330:                    {
                   6331:                      /* CSS within an HTML comment */
                   6332:                      HTMLcomment = TRUE;
                   6333:                      CSSindex++;
                   6334:                      CSSbuffer[CSSindex] = c;
                   6335:                    }
                   6336:                  else if (c == EOS)
                   6337:                    CSSindex++;
                   6338:                }
                   6339:              break;
                   6340:            case '-':
1.234     vatton   6341:              if (!fontface && !page && !quoted &&
                   6342:                  CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
1.82      cvs      6343:                  HTMLcomment)
                   6344:                /* CSS within an HTML comment */
                   6345:                noRule = TRUE;
                   6346:              break;
                   6347:            case '>':
1.234     vatton   6348:              if (!fontface && !page && !quoted && HTMLcomment)
1.82      cvs      6349:                noRule = TRUE;
                   6350:              break;
                   6351:            case ' ':
1.135     vatton   6352:              if (!quoted && import != MAX_CSS_LENGTH && openRule == 0)
1.234     vatton   6353:                  media = !strncasecmp (&CSSbuffer[import+1], "media", 5);
1.82      cvs      6354:              break;
                   6355:            case '{':
1.135     vatton   6356:              if (!quoted)
1.82      cvs      6357:                {
1.135     vatton   6358:                  openRule++;
1.234     vatton   6359:                  if (import != MAX_CSS_LENGTH)
1.135     vatton   6360:                    {
1.234     vatton   6361:                      if (openRule == 1 && media)
                   6362:                        {
                   6363:                          /* is it the screen concerned? */
                   6364:                          CSSbuffer[CSSindex+1] = EOS;
                   6365:                          if (TtaIsPrinting ())
                   6366:                            base = strstr (&CSSbuffer[import], "print");
                   6367:                          else
1.271     vatton   6368:                            base = strstr (&CSSbuffer[import], screentype);
1.234     vatton   6369:                          if (base == NULL)
                   6370:                            base = strstr (&CSSbuffer[import], "all");
                   6371:                          if (base == NULL)
                   6372:                            ignore = TRUE;
1.235     vatton   6373:                          noRule = TRUE;
1.234     vatton   6374:                        }
                   6375:                      else if (!strncasecmp (&CSSbuffer[import+1], "page", 4))
1.235     vatton   6376:                        {
                   6377:                          page = TRUE;
                   6378:                          noRule = TRUE;
                   6379:                        }
1.234     vatton   6380:                      else if (!strncasecmp (&CSSbuffer[import+1], "font-face", 9))
1.235     vatton   6381:                        {
                   6382:                          fontface = TRUE;
                   6383:                          noRule = TRUE;
                   6384:                        }
1.135     vatton   6385:                    }
                   6386:                }
                   6387:              break;
                   6388:            case '}':
                   6389:              if (!quoted)
                   6390:                {
                   6391:                  openRule--;
1.234     vatton   6392:                  if (page)
                   6393:                    {
                   6394:                      noRule = TRUE;
                   6395:                      page = FALSE; /* close the page section */
                   6396:                    }
                   6397:                  else if (fontface)
                   6398:                    {
                   6399:                      noRule = TRUE;
                   6400:                      fontface = FALSE; /* close the fontface section */
                   6401:                    }
                   6402:                  else if (openRule == 0 && import != MAX_CSS_LENGTH)
1.135     vatton   6403:                    {
                   6404:                      import = MAX_CSS_LENGTH;
                   6405:                      noRule = TRUE;
1.234     vatton   6406:                      ignore = FALSE;
1.135     vatton   6407:                      media = FALSE;
                   6408:                    }
1.82      cvs      6409:                  else
1.135     vatton   6410:                    toParse = TRUE;
1.82      cvs      6411:                }
                   6412:              break;
1.135     vatton   6413:            case '"':
                   6414:              if (quoted)
1.82      cvs      6415:                {
1.135     vatton   6416:                  if (CSSbuffer[CSSindex - 1] != '\\')
                   6417:                    quoted = FALSE;
1.82      cvs      6418:                }
                   6419:              else
1.135     vatton   6420:                quoted = TRUE;
1.82      cvs      6421:              break;
                   6422:            default:
1.86      cvs      6423:              if (c == EOL)
1.93      vatton   6424:                newlines++;
1.82      cvs      6425:              break;
                   6426:            }
                   6427:         }
1.93      vatton   6428:       else if (c == EOL)
1.217     vatton   6429:        {
                   6430:          LineNumber++;
                   6431:          c = CR;
                   6432:        }
1.234     vatton   6433: 
1.82      cvs      6434:       if (c != CR)
                   6435:        CSSindex++;
                   6436: 
                   6437:       if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
                   6438:        /* we're still parsing a comment: remove the text comment */
                   6439:        CSSindex = CSScomment;
                   6440: 
                   6441:       if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
                   6442:        {
                   6443:          CSSbuffer[CSSindex] = EOS;
                   6444:          /* parse a not empty string */
                   6445:          if (CSSindex > 0)
                   6446:            {
1.50      cvs      6447:               /* apply CSS rule if it's not just a saving of text */
1.234     vatton   6448:               if (!noRule && !ignore)
1.88      cvs      6449:                {
                   6450:                  /* future import rules must be ignored */
                   6451:                  ignoreImport = TRUE;
1.217     vatton   6452:                  NewLineSkipped = 0;
1.210     vatton   6453:                  ParseStyleDeclaration (NULL, CSSbuffer, docRef, refcss,
1.231     vatton   6454:                                         pInfo->PiLink, url, FALSE);
1.93      vatton   6455:                  LineNumber += newlines;
                   6456:                  newlines = 0;
1.88      cvs      6457:                }
1.82      cvs      6458:               else if (import != MAX_CSS_LENGTH &&
                   6459:                       !strncasecmp (&CSSbuffer[import+1], "import", 6))
                   6460:                {
                   6461:                  /* import section */
                   6462:                  cssRule = &CSSbuffer[import+7];
                   6463:                  cssRule = TtaSkipBlanks (cssRule);
1.93      vatton   6464:                  /* save the current line number */
                   6465:                  newlines += LineNumber;
1.82      cvs      6466:                  if (!strncasecmp (cssRule, "url", 3))
                   6467:                    {
1.50      cvs      6468:                       cssRule = &cssRule[3];
1.82      cvs      6469:                       cssRule = TtaSkipBlanks (cssRule);
                   6470:                       if (*cssRule == '(')
                   6471:                        {
                   6472:                          cssRule++;
                   6473:                          cssRule = TtaSkipBlanks (cssRule);
1.102     vatton   6474:                          quoted = (*cssRule == '"' || *cssRule == '\'');
                   6475:                          if (quoted)
                   6476:                            cssRule++;
1.82      cvs      6477:                          base = cssRule;
                   6478:                          while (*cssRule != EOS && *cssRule != ')')
                   6479:                            cssRule++;
1.102     vatton   6480:                          if (quoted)
1.167     vatton   6481:                            {
                   6482:                              /* isolate the file name */
                   6483:                              cssRule[-1] = EOS;
                   6484:                              quoted = FALSE;
                   6485:                            }
1.216     vatton   6486:                          else
                   6487:                            {
                   6488:                              /* remove extra spaces */
                   6489:                              if (cssRule[-1] == SPACE)
                   6490:                                {
                   6491:                                  *cssRule = SPACE;
                   6492:                                  cssRule--;
                   6493:                                  while (cssRule[-1] == SPACE)
                   6494:                                    cssRule--;
                   6495:                                }
                   6496:                            }
1.160     vatton   6497:                          *cssRule = EOS;
1.82      cvs      6498:                        }
                   6499:                    }
1.87      cvs      6500:                  else if (*cssRule == '"')
                   6501:                    {
1.88      cvs      6502:                      /*
                   6503:                        Do we have to accept single quotes?
1.306     quint    6504:                        Double quotes are accepted here.
1.88      cvs      6505:                        Escaped quotes are not handled. See function SkipQuotedString
                   6506:                      */
1.87      cvs      6507:                      cssRule++;
                   6508:                      cssRule = TtaSkipBlanks (cssRule);
                   6509:                      base = cssRule;
1.179     vatton   6510:                      while (*cssRule != EOS &&
                   6511:                             (*cssRule != '"' ||
1.180     vatton   6512:                              (*cssRule == '"' && cssRule[-1] == '\\')))
1.87      cvs      6513:                        cssRule++;
1.160     vatton   6514:                      /* isolate the file name */
                   6515:                      *cssRule = EOS;
1.133     vatton   6516:                    }
                   6517:                  /* check if a media is defined */
                   6518:                  cssRule++;
                   6519:                  cssRule = TtaSkipBlanks (cssRule);
                   6520:                  if (*cssRule != ';')
                   6521:                    {
                   6522:                      if (TtaIsPrinting ())
                   6523:                        ignoreImport = (strncasecmp (cssRule, "print", 5) &&
                   6524:                                        strncasecmp (cssRule, "all", 3));
                   6525:                      else
                   6526:                        ignoreImport = (strncasecmp (cssRule, "screen", 6) &&
                   6527:                                        strncasecmp (cssRule, "all", 3));
                   6528:                    }
                   6529:                  if (!ignoreImport)
                   6530:                    {
                   6531:                      /* save the displayed URL when an error is reported */
                   6532:                      saveDocURL = DocURL;
1.138     vatton   6533:                      ptr = TtaStrdup (base);
                   6534:                      /* get the CSS URI in UTF-8 */
1.285     cvs      6535:                      /*ptr = ReallocUTF8String (ptr, docRef);*/
1.206     vatton   6536:                      LoadStyleSheet (base, docRef, (Element) css, css,
1.300     vatton   6537:                                      url, pInfo->PiMedia,
1.206     vatton   6538:                                      pInfo->PiCategory == CSS_USER_STYLE);
1.133     vatton   6539:                      /* restore the displayed URL when an error is reported */
                   6540:                      DocURL = saveDocURL;
1.138     vatton   6541:                      TtaFreeMemory (ptr);
1.82      cvs      6542:                    }
1.93      vatton   6543:                  /* restore the number of lines */
                   6544:                  LineNumber = newlines;
                   6545:                  newlines = 0;
1.217     vatton   6546:                  NewLineSkipped = 0;
1.82      cvs      6547:                  import = MAX_CSS_LENGTH;
                   6548:                }
1.234     vatton   6549:              else
                   6550:                {
                   6551:                  LineNumber += newlines;
                   6552:                  newlines = 0;
                   6553:                }
1.82      cvs      6554:            }
                   6555:          toParse = FALSE;
                   6556:          noRule = FALSE;
                   6557:          CSSindex = 0;
1.50      cvs      6558:         }
1.82      cvs      6559:     }
1.6       cvs      6560:   /* restore the display mode */
                   6561:   if (dispMode == DisplayImmediately)
1.82      cvs      6562:     TtaSetDisplayMode (docRef, dispMode);
1.86      cvs      6563: 
                   6564:   /* Prepare the context for style attributes */
                   6565:   DocURL = DocumentURLs[docRef];
                   6566:   LineNumber = -1;
1.1       cvs      6567:   return (c);
                   6568: }

Webmaster