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

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

Webmaster