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

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

Webmaster