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

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

Webmaster