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

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

Webmaster