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

1.1       cvs         1: /*
                      2:  *
1.78      cvs         3:  *  (c) COPYRIGHT MIT and INRIA, 1996-2001
1.1       cvs         4:  *  Please first read the full copyright statement in file COPYRIGHT.
                      5:  *
                      6:  */
1.53      cvs         7:  
1.1       cvs         8: /*
                      9:  * Everything directly linked to the CSS syntax should now hopefully
                     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.61      cvs        21: #include "GraphML.h"
1.1       cvs        22: 
                     23: typedef struct _BackgroundImageCallbackBlock
                     24: {
                     25:   Element                     el;
                     26:   PSchema                     tsch;
                     27:   union
                     28:   {
                     29:     PresentationContextBlock  specific;
                     30:     GenericContextBlock       generic;
                     31:   } context;
                     32: }
                     33: BackgroundImageCallbackBlock, *BackgroundImageCallbackPtr;
                     34: 
                     35: #include "AHTURLTools_f.h"
                     36: #include "HTMLpresentation_f.h"
                     37: #include "HTMLimage_f.h"
                     38: #include "UIcss_f.h"
                     39: #include "css_f.h"
1.24      cvs        40: #include "fetchHTMLname_f.h"
1.91      cvs        41: #include "fetchXMLname_f.h"
1.1       cvs        42: #include "html2thot_f.h"
1.91      cvs        43: #include "init_f.h"
1.1       cvs        44: #include "styleparser_f.h"
                     45: 
                     46: #define MAX_BUFFER_LENGTH 200
                     47: /*
                     48:  * A PropertyParser is a function used to parse  the
                     49:  * description substring associated to a given style attribute
1.59      cvs        50:  * e.g.: "red" for a color attribute or "12pt bold helvetica"
1.1       cvs        51:  * for a font attribute.
                     52:  */
1.79      cvs        53: typedef char *(*PropertyParser) (Element element,
1.56      cvs        54:                                   PSchema tsch,
                     55:                                   PresentationContext context,
1.79      cvs        56:                                   char *cssRule,
1.56      cvs        57:                                   CSSInfoPtr css,
                     58:                                   ThotBool isHTML);
1.1       cvs        59: 
                     60: /* Description of the set of CSS properties supported */
                     61: typedef struct CSSProperty
                     62:   {
1.79      cvs        63:      char                *name;
1.25      cvs        64:      PropertyParser       parsing_function;
1.1       cvs        65:   }
                     66: CSSProperty;
                     67: 
                     68: struct unit_def
                     69: {
1.79      cvs        70:    char               *sign;
1.1       cvs        71:    unsigned int        unit;
                     72: };
                     73: 
                     74: static struct unit_def CSSUnitNames[] =
                     75: {
1.82      cvs        76:    {"pt", STYLE_UNIT_PT},
                     77:    {"pc", STYLE_UNIT_PC},
                     78:    {"in", STYLE_UNIT_IN},
                     79:    {"cm", STYLE_UNIT_CM},
                     80:    {"mm", STYLE_UNIT_MM},
                     81:    {"em", STYLE_UNIT_EM},
                     82:    {"px", STYLE_UNIT_PX},
                     83:    {"ex", STYLE_UNIT_XHEIGHT},
                     84:    {"%", STYLE_UNIT_PERCENT}
1.1       cvs        85: };
                     86: 
                     87: #define NB_UNITS (sizeof(CSSUnitNames) / sizeof(struct unit_def))
1.86      cvs        88: static char         *DocURL = NULL; /* The parsed CSS file */
                     89: static Document      ParsedDoc; /* The document to which CSS are to be applied */
                     90: static int           LineNumber = -1; /* The line where the error occurs */
1.93      vatton     91: static int           NewLineSkipped = 0;
1.1       cvs        92: 
                     93: /*----------------------------------------------------------------------
                     94:    SkipWord:                                                  
                     95:   ----------------------------------------------------------------------*/
1.79      cvs        96: static char *SkipWord (char *ptr)
1.1       cvs        97: {
1.50      cvs        98: # ifdef _WINDOWS
                     99:   /* iswalnum is supposed to be supported by the i18n veriosn of libc 
                    100:      use it when available */
1.82      cvs       101:   while (iswalnum (*ptr) || *ptr == '-' || *ptr == '%')
1.50      cvs       102: # else  /* !_WINDOWS */
1.82      cvs       103:   while (isalnum((int)*ptr) || *ptr == '-' || *ptr == '%')
1.50      cvs       104: # endif /* !_WINDOWS */
                    105:         ptr++;
1.1       cvs       106:   return (ptr);
                    107: }
                    108: 
                    109: /*----------------------------------------------------------------------
1.13      cvs       110:    SkipBlanksAndComments:                                                  
                    111:   ----------------------------------------------------------------------*/
1.82      cvs       112: char *SkipBlanksAndComments (char *ptr)
1.13      cvs       113: {
1.93      vatton    114:   /* skip spaces */
                    115:   while (*ptr == SPACE || *ptr == BSPACE || *ptr == EOL ||
                    116:         *ptr == TAB || *ptr == __CR__)
                    117:     {
                    118:       if (*ptr == EOL)
                    119:        /* increment the number of newline skipped */
                    120:        NewLineSkipped++;
                    121:       ptr++;
                    122:     }
1.13      cvs       123:   while (ptr[0] == '/' && ptr[1] == '*')
                    124:     {
                    125:       /* look for the end of the comment */
                    126:       ptr = &ptr[2];
                    127:       while (ptr[0] != EOS && (ptr[0] != '*' || ptr[1] != '/'))
                    128:        ptr++;
                    129:       if (ptr[0] != EOS)
                    130:        ptr = &ptr[2];
1.93      vatton    131:       /* skip spaces */
                    132:       while (*ptr == SPACE || *ptr == BSPACE || *ptr == EOL ||
                    133:             *ptr == TAB || *ptr == __CR__)
                    134:        {
                    135:          if (*ptr == EOL)
                    136:            /* increment the number of newline skipped */
                    137:            NewLineSkipped++;
                    138:          ptr++;
                    139:        }
1.13      cvs       140:     }
                    141:   return (ptr);
                    142: }
                    143: 
1.49      cvs       144: 
                    145: /*----------------------------------------------------------------------
1.1       cvs       146:    SkipQuotedString:                                                  
                    147:   ----------------------------------------------------------------------*/
1.79      cvs       148: static char *SkipQuotedString (char *ptr, char quote)
1.1       cvs       149: {
1.14      cvs       150:   ThotBool     stop;
1.1       cvs       151: 
                    152:   stop = FALSE;
                    153:   while (!stop)
                    154:     {
                    155:     if (*ptr == quote)
                    156:        {
                    157:        ptr++;
                    158:        stop = TRUE;
                    159:        }
1.82      cvs       160:     else if (*ptr == EOS)
1.1       cvs       161:        stop = TRUE;
1.82      cvs       162:     else if (*ptr == '\\')
1.1       cvs       163:        /* escape character */
                    164:        {
                    165:        ptr++;
1.82      cvs       166:        if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
                    167:           (*ptr >= 'a' && *ptr <= 'f'))
1.1       cvs       168:          {
                    169:          ptr++;
1.82      cvs       170:           if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
                    171:              (*ptr >= 'a' && *ptr <= 'f'))
1.1       cvs       172:             ptr++;
                    173:          }
                    174:        else
                    175:          ptr++;
                    176:        }
                    177:     else
                    178:        ptr++;
                    179:     }
                    180:   return (ptr);
                    181: }
                    182: 
                    183: /*----------------------------------------------------------------------
1.86      cvs       184:    CSSParseError
                    185:    print the error message msg on stderr.
                    186:    When the line is 0 ask to expat the current line number
                    187:   ----------------------------------------------------------------------*/
                    188: static void  CSSParseError (char *msg, char *value)
                    189: {
                    190:   if (!TtaIsPrinting () && ParsedDoc > 0)
                    191:     {
                    192:       if (!ErrFile)
                    193:        {
1.90      cvs       194:          if (OpenParsingErrors (ParsedDoc) == FALSE)
1.86      cvs       195:            return;
                    196:        }
                    197: 
                    198:       if (DocURL != NULL)
                    199:        {
1.94      cvs       200:          fprintf (ErrFile, "*** Errors/warnings in %s\n", DocURL);
1.86      cvs       201:          /* set to NULL as long as the CSS file doesn't change */
                    202:          DocURL = NULL;
                    203:        }
1.89      cvs       204:       CSSErrorsFound = TRUE;
1.86      cvs       205:       if (LineNumber < 0)
                    206:        fprintf (ErrFile, "  In Style attribute %s %s\n", msg, value);
                    207:       else
1.93      vatton    208:        fprintf (ErrFile, "  line %d: %s %s\n", LineNumber + NewLineSkipped,
                    209:                 msg, value);
1.86      cvs       210:     }
                    211: }
                    212: 
1.89      cvs       213: 
1.86      cvs       214: /*----------------------------------------------------------------------
                    215:    SkipProperty:                                                  
                    216:   ----------------------------------------------------------------------*/
                    217: static char *SkipProperty (char *ptr)
                    218: {
                    219:   char       *deb;
                    220:   char        c;
                    221: 
                    222:   deb = ptr;
                    223:   while (*ptr != EOS && *ptr != ';' && *ptr != '}')
                    224:     ptr++;
1.95    ! cvs       225:   /* print the skipped property */
1.86      cvs       226:   c = *ptr;
                    227:   *ptr = EOS;
1.95    ! cvs       228: #ifdef CSS_WARNING
1.86      cvs       229:   if (*deb != EOS)
1.95    ! cvs       230:     CSSParseError ("CSS property ignored:", deb);
        !           231: #endif /* CSS_WARNING */
1.86      cvs       232:   *ptr = c;
                    233:   return (ptr);
                    234: }
                    235: 
                    236: /*----------------------------------------------------------------------
1.1       cvs       237:    SkipProperty:                                                  
                    238:   ----------------------------------------------------------------------*/
1.86      cvs       239: static char *SkipValue (char *ptr)
1.1       cvs       240: {
1.86      cvs       241:   char       *deb;
                    242:   char        c;
                    243: 
                    244:   deb = ptr;
1.82      cvs       245:   while (*ptr != EOS && *ptr != ';' && *ptr != '}')
1.1       cvs       246:     ptr++;
1.95    ! cvs       247:   /* print the skipped property */
1.86      cvs       248:   c = *ptr;
                    249:   *ptr = EOS;
1.95    ! cvs       250: #ifdef CSS_WARNING
1.86      cvs       251:   if (*deb != EOS && *deb != ',')
1.95    ! cvs       252:     CSSParseError ("CSS value ignored:", deb);
        !           253: #endif /* CSS_WARNING */
1.86      cvs       254:   *ptr = c;
1.1       cvs       255:   return (ptr);
                    256: }
                    257: 
                    258: /*----------------------------------------------------------------------
1.64      cvs       259:    ParseNumber:                                                  
                    260:    parse a number and returns the corresponding value.
1.1       cvs       261:   ----------------------------------------------------------------------*/
1.79      cvs       262: char *ParseNumber (char *cssRule, PresentationValue *pval)
1.1       cvs       263: {
                    264:   int                 val = 0;
                    265:   int                 minus = 0;
                    266:   int                 valid = 0;
                    267:   int                 f = 0;
1.14      cvs       268:   ThotBool            real = FALSE;
1.1       cvs       269: 
                    270:   pval->typed_data.unit = STYLE_UNIT_REL;
                    271:   pval->typed_data.real = FALSE;
1.82      cvs       272:   cssRule = SkipBlanksAndComments (cssRule);
                    273:   if (*cssRule == '-')
1.1       cvs       274:     {
                    275:       minus = 1;
                    276:       cssRule++;
1.82      cvs       277:       cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs       278:     }
                    279: 
1.82      cvs       280:   if (*cssRule == '+')
1.1       cvs       281:     {
                    282:       cssRule++;
1.82      cvs       283:       cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs       284:     }
                    285: 
1.82      cvs       286:   while ((*cssRule >= '0') && (*cssRule <= '9'))
1.1       cvs       287:     {
                    288:       val *= 10;
1.82      cvs       289:       val += *cssRule - '0';
1.1       cvs       290:       cssRule++;
                    291:       valid = 1;
                    292:     }
                    293: 
1.82      cvs       294:   if (*cssRule == '.')
1.1       cvs       295:     {
                    296:       real = TRUE;
                    297:       f = val;
                    298:       val = 0;
                    299:       cssRule++;
                    300:       /* keep only 3 digits */
1.82      cvs       301:       if (*cssRule >= '0' && *cssRule <= '9')
1.1       cvs       302:        {
1.82      cvs       303:          val = (*cssRule - '0') * 100;
1.1       cvs       304:          cssRule++;
1.82      cvs       305:          if (*cssRule >= '0' && *cssRule <= '9')
1.1       cvs       306:            {
1.82      cvs       307:              val += (*cssRule - '0') * 10;
1.1       cvs       308:              cssRule++;
1.82      cvs       309:              if ((*cssRule >= '0') && (*cssRule <= '9'))
1.1       cvs       310:                {
1.82      cvs       311:                  val += *cssRule - '0';
1.1       cvs       312:                  cssRule++;
                    313:                }
                    314:            }
                    315: 
1.82      cvs       316:          while (*cssRule >= '0' && *cssRule <= '9')
1.1       cvs       317:            cssRule++;
                    318:          valid = 1;
                    319:        }
                    320:     }
                    321: 
                    322:   if (!valid)
                    323:     {
                    324:       pval->typed_data.unit = STYLE_UNIT_INVALID;
                    325:       pval->typed_data.value = 0;
                    326:     }
                    327:   else
                    328:     {
                    329:       pval->typed_data.real = real;
                    330:       if (real)
                    331:        {
                    332:          if (minus)
                    333:            pval->typed_data.value = -(f * 1000 + val);
                    334:          else
                    335:            pval->typed_data.value = f * 1000 + val;
                    336:        }
                    337:       else
                    338:        {
                    339:          if (minus)
                    340:            pval->typed_data.value = -val;
                    341:          else
                    342:            pval->typed_data.value = val;
                    343:        }
1.64      cvs       344:     }
                    345:   return (cssRule);
                    346: }
                    347: 
                    348: /*----------------------------------------------------------------------
                    349:    ParseCSSUnit:                                                  
                    350:    parse a CSS Unit substring and returns the corresponding      
                    351:    value and its unit.                                           
                    352:   ----------------------------------------------------------------------*/
1.82      cvs       353: char *ParseCSSUnit (char *cssRule, PresentationValue *pval)
1.64      cvs       354: {
                    355:   unsigned int        uni;
                    356: 
                    357:   pval->typed_data.unit = STYLE_UNIT_REL;
                    358:   cssRule = ParseNumber (cssRule, pval);
                    359:   if (pval->typed_data.unit == STYLE_UNIT_INVALID)
                    360:       cssRule = SkipWord (cssRule);
                    361:   else
                    362:     {
1.82      cvs       363:       cssRule = SkipBlanksAndComments (cssRule);
1.64      cvs       364:       for (uni = 0; uni < NB_UNITS; uni++)
                    365:        {
1.82      cvs       366:          if (!strncasecmp (CSSUnitNames[uni].sign, cssRule,
                    367:                             strlen (CSSUnitNames[uni].sign)))
1.64      cvs       368:            {
                    369:              pval->typed_data.unit = CSSUnitNames[uni].unit;
1.82      cvs       370:              return (cssRule + strlen (CSSUnitNames[uni].sign));
1.64      cvs       371:            }
                    372:        }
                    373:       /* not in the list of predefined units */
                    374:       pval->typed_data.unit = STYLE_UNIT_PX;
1.1       cvs       375:     }
                    376:   return (cssRule);
                    377: }
                    378: 
1.43      cvs       379: /*----------------------------------------------------------------------
                    380:    ParseBorderValue                                       
                    381:   ----------------------------------------------------------------------*/
1.79      cvs       382: static char *ParseBorderValue (char *cssRule, PresentationValue *border)
1.43      cvs       383: {
                    384:   /* first parse the attribute string */
                    385:    border->typed_data.value = 0;
1.44      cvs       386:    border->typed_data.unit = STYLE_UNIT_INVALID;
1.43      cvs       387:    border->typed_data.real = FALSE;
1.82      cvs       388:    if (!strncasecmp (cssRule, "thin", 4))
1.43      cvs       389:      {
1.44      cvs       390:        border->typed_data.unit = STYLE_UNIT_PX;
1.43      cvs       391:        border->typed_data.value = 1;
                    392:        cssRule = SkipWord (cssRule);
                    393:      }
1.82      cvs       394:    else if (!strncasecmp (cssRule, "medium", 6))
1.43      cvs       395:      {
1.44      cvs       396:        border->typed_data.unit = STYLE_UNIT_PX;
1.43      cvs       397:        border->typed_data.value = 3;
                    398:        cssRule = SkipWord (cssRule);
                    399:      }
1.82      cvs       400:    else if (!strncasecmp (cssRule, "thick", 5))
1.43      cvs       401:      {
1.44      cvs       402:        border->typed_data.unit = STYLE_UNIT_PX;
1.43      cvs       403:        border->typed_data.value = 5;
                    404:        cssRule = SkipWord (cssRule);
                    405:      }
1.82      cvs       406:    else if (isdigit (*cssRule))
1.43      cvs       407:      cssRule = ParseCSSUnit (cssRule, border);
                    408:    return (cssRule);
                    409: }
                    410: 
                    411: /*----------------------------------------------------------------------
                    412:    ParseBorderStyle                                      
                    413:   ----------------------------------------------------------------------*/
1.79      cvs       414: static char *ParseBorderStyle (char *cssRule, PresentationValue *border)
1.43      cvs       415: {
                    416:   /* first parse the attribute string */
                    417:    border->typed_data.value = 0;
                    418:    border->typed_data.unit = STYLE_UNIT_PX;
                    419:    border->typed_data.real = FALSE;
1.82      cvs       420:    if (!strncasecmp (cssRule, "none", 4))
1.43      cvs       421:      border->typed_data.value = STYLE_BORDERNONE;
1.82      cvs       422:    else if (!strncasecmp (cssRule, "hidden", 6))
1.43      cvs       423:      border->typed_data.value = STYLE_BORDERHIDDEN;
1.82      cvs       424:    else if (!strncasecmp (cssRule, "dotted", 6))
1.43      cvs       425:      border->typed_data.value = STYLE_BORDERDOTTED;
1.82      cvs       426:    else if (!strncasecmp (cssRule, "dashed", 6))
1.43      cvs       427:      border->typed_data.value = STYLE_BORDERDASHED;
1.82      cvs       428:    else if (!strncasecmp (cssRule, "solid", 5))
1.43      cvs       429:      border->typed_data.value = STYLE_BORDERSOLID;
1.82      cvs       430:    else if (!strncasecmp (cssRule, "double", 6))
1.43      cvs       431:      border->typed_data.value = STYLE_BORDERDOUBLE;
1.82      cvs       432:    else if (!strncasecmp (cssRule, "groove", 6))
1.43      cvs       433:      border->typed_data.value = STYLE_BORDERGROOVE;
1.82      cvs       434:    else if (!strncasecmp (cssRule, "ridge", 5))
1.43      cvs       435:      border->typed_data.value = STYLE_BORDERRIDGE;
1.82      cvs       436:    else if (!strncasecmp (cssRule, "inset", 5))
1.43      cvs       437:      border->typed_data.value = STYLE_BORDERINSET;
1.82      cvs       438:    else if (!strncasecmp (cssRule, "outset", 6))
1.43      cvs       439:      border->typed_data.value = STYLE_BORDEROUTSET;
                    440:    else
1.44      cvs       441:      {
                    442:        /* invalid style */
                    443:        border->typed_data.unit = STYLE_UNIT_INVALID;
                    444:        return (cssRule);
                    445:      }
1.43      cvs       446:    /* the value is parsed now */
                    447:    cssRule = SkipWord (cssRule);
                    448:    return (cssRule);
                    449: }
                    450: 
                    451: /*----------------------------------------------------------------------
1.59      cvs       452:    ParseCSSColor: parse a CSS color attribute string    
1.43      cvs       453:    we expect the input string describing the attribute to be     
                    454:    either a color name, a 3 tuple or an hexadecimal encoding.    
                    455:    The color used will be approximed from the current color      
                    456:    table                                                         
                    457:   ----------------------------------------------------------------------*/
1.79      cvs       458: static char *ParseCSSColor (char *cssRule, PresentationValue * val)
1.43      cvs       459: {
1.79      cvs       460:   char               *ptr;
1.43      cvs       461:   unsigned short      redval = (unsigned short) -1;
                    462:   unsigned short      greenval = 0;    /* composant of each RGB       */
                    463:   unsigned short      blueval = 0;     /* default to red if unknown ! */
                    464:   int                 best = 0;        /* best color in list found */
                    465: 
1.82      cvs       466:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs       467:   val->typed_data.unit = STYLE_UNIT_INVALID;
                    468:   val->typed_data.real = FALSE;
                    469:   val->typed_data.value = 0;
1.57      cvs       470:   ptr = TtaGiveRGB (cssRule, &redval, &greenval, &blueval);
                    471:   if (ptr == cssRule)
1.43      cvs       472:     {
1.86      cvs       473:       cssRule = SkipValue (cssRule);
1.43      cvs       474:       val->typed_data.value = 0;
                    475:       val->typed_data.unit = STYLE_UNIT_INVALID;
                    476:     }
                    477:   else
                    478:     {
                    479:       best = TtaGetThotColor (redval, greenval, blueval);
                    480:       val->typed_data.value = best;
                    481:       val->typed_data.unit = STYLE_UNIT_REL;
1.57      cvs       482:       cssRule = ptr;
1.43      cvs       483:     }
                    484:   val->typed_data.real = FALSE;
1.65      cvs       485:   return (cssRule);
1.43      cvs       486: }
1.1       cvs       487: 
                    488: /*----------------------------------------------------------------------
1.59      cvs       489:    ParseCSSBorderTopWidth: parse a CSS BorderTopWidth
1.1       cvs       490:    attribute string.                                          
                    491:   ----------------------------------------------------------------------*/
1.79      cvs       492: static char *ParseCSSBorderTopWidth (Element element, PSchema tsch,
                    493:                                       PresentationContext context, 
                    494:                                       char *cssRule, CSSInfoPtr css,
                    495:                                       ThotBool isHTML)
1.1       cvs       496: {
1.41      cvs       497:   PresentationValue   border;
                    498:   
1.82      cvs       499:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs       500:   cssRule = ParseBorderValue (cssRule, &border);
                    501:   if (border.typed_data.unit != STYLE_UNIT_INVALID)
1.44      cvs       502:     {
                    503:       TtaSetStylePresentation (PRBorderTopWidth, element, tsch, context, border);
                    504:       border.typed_data.value = 1;
                    505:       border.typed_data.unit = STYLE_UNIT_REL;
                    506:     }
1.1       cvs       507:   return (cssRule);
                    508: }
                    509: 
                    510: /*----------------------------------------------------------------------
1.59      cvs       511:    ParseCSSBorderBottomWidth: parse a CSS BorderBottomWidth
1.1       cvs       512:    attribute string.                                          
                    513:   ----------------------------------------------------------------------*/
1.79      cvs       514: static char *ParseCSSBorderBottomWidth (Element element, PSchema tsch,
                    515:                                          PresentationContext context,
                    516:                                          char *cssRule, CSSInfoPtr css,
                    517:                                          ThotBool isHTML)
1.1       cvs       518: {
1.41      cvs       519:   PresentationValue   border;
                    520:   
1.82      cvs       521:   cssRule = SkipBlanksAndComments (cssRule);
1.41      cvs       522:   /* first parse the attribute string */
1.43      cvs       523:   cssRule = ParseBorderValue (cssRule, &border);
                    524:   if (border.typed_data.unit != STYLE_UNIT_INVALID)
1.44      cvs       525:     {
                    526:       TtaSetStylePresentation (PRBorderBottomWidth, element, tsch, context, border);
                    527:       border.typed_data.value = 1;
                    528:       border.typed_data.unit = STYLE_UNIT_REL;
                    529:     }
1.1       cvs       530:   return (cssRule);
                    531: }
                    532: 
                    533: /*----------------------------------------------------------------------
1.59      cvs       534:    ParseCSSBorderLeftWidth: parse a CSS BorderLeftWidth
1.1       cvs       535:    attribute string.                                          
                    536:   ----------------------------------------------------------------------*/
1.79      cvs       537: static char *ParseCSSBorderLeftWidth (Element element, PSchema tsch,
                    538:                                        PresentationContext context,
                    539:                                        char *cssRule, CSSInfoPtr css,
                    540:                                        ThotBool isHTML)
1.1       cvs       541: {
1.41      cvs       542:   PresentationValue   border;
                    543:   
1.82      cvs       544:   cssRule = SkipBlanksAndComments (cssRule);
1.41      cvs       545:   /* first parse the attribute string */
1.43      cvs       546:   cssRule = ParseBorderValue (cssRule, &border);
                    547:   if (border.typed_data.unit != STYLE_UNIT_INVALID)
1.44      cvs       548:     {
                    549:       TtaSetStylePresentation (PRBorderLeftWidth, element, tsch, context, border);
                    550:       border.typed_data.value = 1;
                    551:       border.typed_data.unit = STYLE_UNIT_REL;
                    552:     }
1.1       cvs       553:   return (cssRule);
                    554: }
                    555: 
                    556: /*----------------------------------------------------------------------
1.59      cvs       557:    ParseCSSBorderRightWidth: parse a CSS BorderRightWidth
1.1       cvs       558:    attribute string.                                          
                    559:   ----------------------------------------------------------------------*/
1.79      cvs       560: static char *ParseCSSBorderRightWidth (Element element, PSchema tsch,
                    561:                                         PresentationContext context,
                    562:                                         char *cssRule, CSSInfoPtr css,
                    563:                                         ThotBool isHTML)
1.1       cvs       564: {
1.41      cvs       565:   PresentationValue   border;
                    566:   
1.82      cvs       567:   cssRule = SkipBlanksAndComments (cssRule);
1.41      cvs       568:   /* first parse the attribute string */
1.43      cvs       569:   cssRule = ParseBorderValue (cssRule, &border);
                    570:   if (border.typed_data.unit != STYLE_UNIT_INVALID)
1.44      cvs       571:     {
                    572:       TtaSetStylePresentation (PRBorderRightWidth, element, tsch, context, border);
                    573:       border.typed_data.value = 1;
                    574:       border.typed_data.unit = STYLE_UNIT_REL;
                    575:     }
1.1       cvs       576:   return (cssRule);
                    577: }
                    578: 
                    579: /*----------------------------------------------------------------------
1.59      cvs       580:    ParseCSSBorderWidth: parse a CSS BorderWidth
1.1       cvs       581:    attribute string.                                          
                    582:   ----------------------------------------------------------------------*/
1.79      cvs       583: static char *ParseCSSBorderWidth (Element element, PSchema tsch,
                    584:                                    PresentationContext context,
                    585:                                    char *cssRule, CSSInfoPtr css,
                    586:                                    ThotBool isHTML)
1.1       cvs       587: {
1.79      cvs       588:   char *ptrT, *ptrR, *ptrB, *ptrL;
1.93      vatton    589:   int   skippedNL;
1.41      cvs       590: 
1.82      cvs       591:   ptrT = SkipBlanksAndComments (cssRule);
1.42      cvs       592:   /* First parse Border-Top */
                    593:   ptrR = ParseCSSBorderTopWidth (element, tsch, context, ptrT, css, isHTML);
1.82      cvs       594:   ptrR = SkipBlanksAndComments (ptrR);
                    595:   if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42      cvs       596:     {
1.93      vatton    597:       skippedNL = NewLineSkipped;
1.42      cvs       598:       cssRule = ptrR;
                    599:       /* apply the Border-Top to all */
                    600:       ptrR = ParseCSSBorderRightWidth (element, tsch, context, ptrT, css, isHTML);
1.93      vatton    601:       NewLineSkipped = skippedNL;
1.42      cvs       602:       ptrR = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
1.93      vatton    603:       NewLineSkipped = skippedNL;
1.42      cvs       604:       ptrR = ParseCSSBorderLeftWidth (element, tsch, context, ptrT, css, isHTML);
                    605:     }
                    606:   else
                    607:     {
                    608:       /* parse Border-Right */
                    609:       ptrB = ParseCSSBorderRightWidth (element, tsch, context, ptrR, css, isHTML);
1.82      cvs       610:       ptrB = SkipBlanksAndComments (ptrB);
                    611:       if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.42      cvs       612:        {
1.93      vatton    613:          skippedNL = NewLineSkipped;
1.42      cvs       614:          cssRule = ptrB;
                    615:          /* apply the Border-Top to Border-Bottom */
                    616:          ptrB = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
1.93      vatton    617:          NewLineSkipped = skippedNL;
1.42      cvs       618:          /* apply the Border-Right to Border-Left */
                    619:          ptrB = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
                    620:        }
                    621:       else
                    622:        {
                    623:          /* parse Border-Bottom */
                    624:          ptrL = ParseCSSBorderBottomWidth (element, tsch, context, ptrB, css, isHTML);
1.82      cvs       625:          ptrL = SkipBlanksAndComments (ptrL);
                    626:          if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.42      cvs       627:            {
                    628:              cssRule = ptrL;
                    629:              /* apply the Border-Right to Border-Left */
                    630:              ptrL = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
                    631:            }
                    632:          else
                    633:            /* parse Border-Left */
                    634:            cssRule = ParseCSSBorderLeftWidth (element, tsch, context, ptrL, css, isHTML);
1.82      cvs       635:          cssRule = SkipBlanksAndComments (cssRule);
1.42      cvs       636:        }
                    637:     }
1.1       cvs       638:   return (cssRule);
                    639: }
                    640: 
                    641: /*----------------------------------------------------------------------
1.59      cvs       642:    ParseCSSBorderColorTop: parse a CSS BorderColorTop
1.1       cvs       643:    attribute string.                                          
                    644:   ----------------------------------------------------------------------*/
1.79      cvs       645: static char *ParseCSSBorderColorTop (Element element, PSchema tsch,
                    646:                                     PresentationContext context,
                    647:                                     char *cssRule, CSSInfoPtr css,
                    648:                                     ThotBool isHTML)
1.1       cvs       649: {
1.43      cvs       650:    PresentationValue   best;
                    651: 
                    652:    cssRule = ParseCSSColor (cssRule, &best);
                    653:    if (best.typed_data.unit != STYLE_UNIT_INVALID)
                    654:      /* install the new presentation */
                    655:      TtaSetStylePresentation (PRBorderTopColor, element, tsch, context, best);
1.65      cvs       656:    return (cssRule);
1.1       cvs       657: }
                    658: 
                    659: /*----------------------------------------------------------------------
1.59      cvs       660:    ParseCSSBorderColorLeft: parse a CSS BorderColorLeft
1.42      cvs       661:    attribute string.                                          
                    662:   ----------------------------------------------------------------------*/
1.79      cvs       663: static char *ParseCSSBorderColorLeft (Element element, PSchema tsch,
                    664:                                      PresentationContext context,
                    665:                                      char *cssRule, CSSInfoPtr css,
                    666:                                      ThotBool isHTML)
1.42      cvs       667: {
1.43      cvs       668:    PresentationValue   best;
                    669: 
                    670:    cssRule = ParseCSSColor (cssRule, &best);
                    671:    if (best.typed_data.unit != STYLE_UNIT_INVALID)
                    672:      /* install the new presentation */
                    673:      TtaSetStylePresentation (PRBorderLeftColor, element, tsch, context, best);
1.65      cvs       674:    return (cssRule);
1.42      cvs       675: }
                    676: 
                    677: /*----------------------------------------------------------------------
1.59      cvs       678:    ParseCSSBorderColorBottom: parse a CSS BorderColorBottom
1.42      cvs       679:    attribute string.                                          
                    680:   ----------------------------------------------------------------------*/
1.79      cvs       681: static char *ParseCSSBorderColorBottom (Element element, PSchema tsch,
                    682:                                        PresentationContext context,
                    683:                                        char *cssRule, CSSInfoPtr css,
                    684:                                        ThotBool isHTML)
1.42      cvs       685: {
1.43      cvs       686:    PresentationValue   best;
                    687: 
                    688:    cssRule = ParseCSSColor (cssRule, &best);
                    689:    if (best.typed_data.unit != STYLE_UNIT_INVALID)
                    690:      /* install the new presentation */
                    691:      TtaSetStylePresentation (PRBorderBottomColor, element, tsch, context, best);
1.65      cvs       692:    return (cssRule);
1.42      cvs       693: }
                    694: 
                    695: /*----------------------------------------------------------------------
1.59      cvs       696:    ParseCSSBorderColorRight: parse a CSS BorderColorRight
1.1       cvs       697:    attribute string.                                          
                    698:   ----------------------------------------------------------------------*/
1.79      cvs       699: static char *ParseCSSBorderColorRight (Element element, PSchema tsch,
                    700:                                       PresentationContext context,
                    701:                                       char *cssRule, CSSInfoPtr css,
                    702:                                       ThotBool isHTML)
1.1       cvs       703: {
1.43      cvs       704:    PresentationValue   best;
                    705: 
                    706:    cssRule = ParseCSSColor (cssRule, &best);
                    707:    if (best.typed_data.unit != STYLE_UNIT_INVALID)
                    708:      /* install the new presentation */
                    709:      TtaSetStylePresentation (PRBorderRightColor, element, tsch, context, best);
1.65      cvs       710:    return (cssRule);
1.1       cvs       711: }
                    712: 
                    713: /*----------------------------------------------------------------------
1.59      cvs       714:    ParseCSSBorderColor: parse a CSS border-color        
1.42      cvs       715:    attribute string.                                          
                    716:   ----------------------------------------------------------------------*/
1.79      cvs       717: static char *ParseCSSBorderColor (Element element, PSchema tsch,
                    718:                                  PresentationContext context,
                    719:                                  char *cssRule, CSSInfoPtr css,
                    720:                                  ThotBool isHTML)
1.42      cvs       721: {
1.79      cvs       722:   char *ptrT, *ptrR, *ptrB, *ptrL;
1.93      vatton    723:   int   skippedNL;
1.42      cvs       724: 
1.82      cvs       725:   ptrT = SkipBlanksAndComments (cssRule);
1.42      cvs       726:   /* First parse Border-Top */
1.43      cvs       727:   ptrR = ParseCSSBorderColorTop (element, tsch, context, ptrT, css, isHTML);
1.82      cvs       728:   ptrR = SkipBlanksAndComments (ptrR);
                    729:   if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42      cvs       730:     {
1.93      vatton    731:       skippedNL = NewLineSkipped;
1.42      cvs       732:       cssRule = ptrR;
                    733:       /* apply the Border-Top to all */
1.43      cvs       734:       ptrR = ParseCSSBorderColorRight (element, tsch, context, ptrT, css, isHTML);
1.93      vatton    735:          NewLineSkipped = skippedNL;
1.43      cvs       736:       ptrR = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton    737:          NewLineSkipped = skippedNL;
1.43      cvs       738:       ptrR = ParseCSSBorderColorLeft (element, tsch, context, ptrT, css, isHTML);
1.42      cvs       739:     }
                    740:   else
                    741:     {
                    742:       /* parse Border-Right */
1.43      cvs       743:       ptrB = ParseCSSBorderColorRight (element, tsch, context, ptrR, css, isHTML);
1.82      cvs       744:       ptrB = SkipBlanksAndComments (ptrB);
                    745:       if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.42      cvs       746:        {
1.93      vatton    747:          skippedNL = NewLineSkipped;
1.42      cvs       748:          cssRule = ptrB;
                    749:          /* apply the Border-Top to Border-Bottom */
1.43      cvs       750:          ptrB = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton    751:          NewLineSkipped = skippedNL;
1.42      cvs       752:          /* apply the Border-Right to Border-Left */
1.43      cvs       753:          ptrB = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1.42      cvs       754:        }
                    755:       else
                    756:        {
1.93      vatton    757:          skippedNL = NewLineSkipped;
1.42      cvs       758:          /* parse Border-Bottom */
1.43      cvs       759:          ptrL = ParseCSSBorderColorBottom (element, tsch, context, ptrB, css, isHTML);
1.93      vatton    760:          NewLineSkipped = skippedNL;
1.82      cvs       761:          ptrL = SkipBlanksAndComments (ptrL);
                    762:          if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.42      cvs       763:            {
                    764:              cssRule = ptrL;
                    765:              /* apply the Border-Right to Border-Left */
1.43      cvs       766:              ptrL = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1.42      cvs       767:            }
                    768:          else
                    769:            /* parse Border-Left */
1.43      cvs       770:            cssRule = ParseCSSBorderColorLeft (element, tsch, context, ptrL, css, isHTML);
1.82      cvs       771:          cssRule = SkipBlanksAndComments (cssRule);
1.42      cvs       772:        }
                    773:     }
                    774:   return (cssRule);
                    775: }
                    776: 
                    777: /*----------------------------------------------------------------------
1.59      cvs       778:    ParseCSSBorderStyleTop: parse a CSS BorderStyleTop
1.42      cvs       779:    attribute string.                                          
                    780:   ----------------------------------------------------------------------*/
1.79      cvs       781: static char *ParseCSSBorderStyleTop (Element element, PSchema tsch,
                    782:                                     PresentationContext context,
                    783:                                     char *cssRule, CSSInfoPtr css,
                    784:                                     ThotBool isHTML)
1.42      cvs       785: {
1.43      cvs       786:   PresentationValue   border;
                    787:   
1.82      cvs       788:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs       789:   cssRule = ParseBorderStyle (cssRule, &border);
                    790:   if (border.typed_data.unit != STYLE_UNIT_INVALID)
                    791:     TtaSetStylePresentation (PRBorderTopStyle, element, tsch, context, border);
1.42      cvs       792:   return (cssRule);
                    793: }
                    794: 
                    795: /*----------------------------------------------------------------------
1.59      cvs       796:    ParseCSSBorderStyleLeft: parse a CSS BorderStyleLeft
1.42      cvs       797:    attribute string.                                          
                    798:   ----------------------------------------------------------------------*/
1.79      cvs       799: static char *ParseCSSBorderStyleLeft (Element element, PSchema tsch,
                    800:                                      PresentationContext context,
                    801:                                      char *cssRule, CSSInfoPtr css,
                    802:                                      ThotBool isHTML)
1.42      cvs       803: {
1.43      cvs       804:   PresentationValue   border;
                    805:   
1.82      cvs       806:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs       807:   cssRule = ParseBorderStyle (cssRule, &border);
                    808:   if (border.typed_data.unit != STYLE_UNIT_INVALID)
                    809:     TtaSetStylePresentation (PRBorderLeftStyle, element, tsch, context, border);
1.42      cvs       810:   return (cssRule);
                    811: }
                    812: 
                    813: /*----------------------------------------------------------------------
1.59      cvs       814:    ParseCSSBorderStyleBottom: parse a CSS BorderStyleBottom
1.1       cvs       815:    attribute string.                                          
                    816:   ----------------------------------------------------------------------*/
1.79      cvs       817: static char *ParseCSSBorderStyleBottom (Element element, PSchema tsch,
                    818:                                        PresentationContext context,
                    819:                                        char *cssRule, CSSInfoPtr css,
                    820:                                        ThotBool isHTML)
1.1       cvs       821: {
1.43      cvs       822:   PresentationValue   border;
                    823:   
1.82      cvs       824:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs       825:   cssRule = ParseBorderStyle (cssRule, &border);
                    826:   if (border.typed_data.unit != STYLE_UNIT_INVALID)
                    827:     TtaSetStylePresentation (PRBorderBottomStyle, element, tsch, context, border);
1.1       cvs       828:   return (cssRule);
                    829: }
                    830: 
                    831: /*----------------------------------------------------------------------
1.59      cvs       832:    ParseCSSBorderStyleRight: parse a CSS BorderStyleRight
1.1       cvs       833:    attribute string.                                          
                    834:   ----------------------------------------------------------------------*/
1.79      cvs       835: static char *ParseCSSBorderStyleRight (Element element, PSchema tsch,
                    836:                                       PresentationContext context,
                    837:                                       char *cssRule, CSSInfoPtr css,
                    838:                                       ThotBool isHTML)
1.1       cvs       839: {
1.43      cvs       840:   PresentationValue   border;
                    841:   
1.82      cvs       842:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs       843:   cssRule = ParseBorderStyle (cssRule, &border);
                    844:   if (border.typed_data.unit != STYLE_UNIT_INVALID)
                    845:     TtaSetStylePresentation (PRBorderRightStyle, element, tsch, context, border);
1.1       cvs       846:   return (cssRule);
                    847: }
                    848: 
                    849: /*----------------------------------------------------------------------
1.59      cvs       850:    ParseCSSBorderStyleStyle: parse a CSS border-style        
1.1       cvs       851:    attribute string.                                          
                    852:   ----------------------------------------------------------------------*/
1.79      cvs       853: static char *ParseCSSBorderStyle (Element element, PSchema tsch,
                    854:                                  PresentationContext context,
                    855:                                  char *cssRule, CSSInfoPtr css,
                    856:                                  ThotBool isHTML)
1.1       cvs       857: {
1.79      cvs       858:   char *ptrT, *ptrR, *ptrB, *ptrL;
1.93      vatton    859:   int   skippedNL;
1.42      cvs       860: 
1.82      cvs       861:   ptrT = SkipBlanksAndComments (cssRule);
1.42      cvs       862:   /* First parse Border-Top */
1.43      cvs       863:   ptrR = ParseCSSBorderStyleTop (element, tsch, context, ptrT, css, isHTML);
1.82      cvs       864:   ptrR = SkipBlanksAndComments (ptrR);
                    865:   if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42      cvs       866:     {
1.93      vatton    867:       skippedNL = NewLineSkipped;
1.42      cvs       868:       cssRule = ptrR;
                    869:       /* apply the Border-Top to all */
1.43      cvs       870:       ptrR = ParseCSSBorderStyleRight (element, tsch, context, ptrT, css, isHTML);
1.93      vatton    871:       NewLineSkipped = skippedNL;
1.43      cvs       872:       ptrR = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton    873:       NewLineSkipped = skippedNL;
1.43      cvs       874:       ptrR = ParseCSSBorderStyleLeft (element, tsch, context, ptrT, css, isHTML);
1.42      cvs       875:     }
                    876:   else
                    877:     {
                    878:       /* parse Border-Right */
1.43      cvs       879:       ptrB = ParseCSSBorderStyleRight (element, tsch, context, ptrR, css, isHTML);
1.82      cvs       880:       ptrB = SkipBlanksAndComments (ptrB);
                    881:       if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.42      cvs       882:        {
1.93      vatton    883:          skippedNL = NewLineSkipped;
1.42      cvs       884:          cssRule = ptrB;
                    885:          /* apply the Border-Top to Border-Bottom */
1.43      cvs       886:          ptrB = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton    887:          NewLineSkipped = skippedNL;
1.42      cvs       888:          /* apply the Border-Right to Border-Left */
1.43      cvs       889:          ptrB = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1.42      cvs       890:        }
                    891:       else
                    892:        {
                    893:          /* parse Border-Bottom */
1.43      cvs       894:          ptrL = ParseCSSBorderStyleBottom (element, tsch, context, ptrB, css, isHTML);
1.82      cvs       895:          ptrL = SkipBlanksAndComments (ptrL);
                    896:          if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.42      cvs       897:            {
                    898:              cssRule = ptrL;
                    899:              /* apply the Border-Right to Border-Left */
1.43      cvs       900:              ptrL = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1.42      cvs       901:            }
                    902:          else
                    903:            /* parse Border-Left */
1.43      cvs       904:            cssRule = ParseCSSBorderStyleLeft (element, tsch, context, ptrL, css, isHTML);
1.82      cvs       905:          cssRule = SkipBlanksAndComments (cssRule);
1.42      cvs       906:        }
                    907:     }
                    908:   return (cssRule);
                    909: }
                    910: 
                    911: /*----------------------------------------------------------------------
1.59      cvs       912:    ParseCSSBorderTop: parse a CSS BorderTop
1.42      cvs       913:    attribute string.                                          
                    914:   ----------------------------------------------------------------------*/
1.79      cvs       915: static char *ParseCSSBorderTop (Element element, PSchema tsch,
                    916:                                PresentationContext context, char *cssRule,
                    917:                                CSSInfoPtr css, ThotBool isHTML)
1.42      cvs       918: {
1.79      cvs       919:   char           *ptr;
1.43      cvs       920: 
1.82      cvs       921:   cssRule = SkipBlanksAndComments (cssRule);
                    922:   while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43      cvs       923:     {
                    924:       ptr = cssRule;
                    925:       cssRule = ParseCSSBorderStyleTop (element, tsch, context, cssRule, css, isHTML);
                    926:       if (ptr == cssRule)
                    927:        cssRule = ParseCSSBorderTopWidth (element, tsch, context, cssRule, css, isHTML);
                    928:       if (ptr == cssRule)
                    929:        cssRule = ParseCSSBorderColorTop (element, tsch, context, cssRule, css, isHTML);
                    930:       if (ptr == cssRule)
                    931:        /* rule not found */
1.86      cvs       932:        cssRule = SkipValue (cssRule);
1.82      cvs       933:       cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs       934:     }
1.42      cvs       935:   return (cssRule);
                    936: }
                    937: 
                    938: /*----------------------------------------------------------------------
1.59      cvs       939:    ParseCSSBorderLeft: parse a CSS BorderLeft
1.42      cvs       940:    attribute string.                                          
                    941:   ----------------------------------------------------------------------*/
1.79      cvs       942: static char *ParseCSSBorderLeft (Element element, PSchema tsch,
                    943:                                 PresentationContext context, char *cssRule,
                    944:                                 CSSInfoPtr css, ThotBool isHTML)
1.42      cvs       945: {
1.79      cvs       946:   char           *ptr;
1.43      cvs       947: 
1.82      cvs       948:   cssRule = SkipBlanksAndComments (cssRule);
                    949:   while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43      cvs       950:     {
                    951:       ptr = cssRule;
                    952:       cssRule = ParseCSSBorderStyleLeft (element, tsch, context, cssRule, css, isHTML);
                    953:       if (ptr == cssRule)
                    954:        cssRule = ParseCSSBorderLeftWidth (element, tsch, context, cssRule, css, isHTML);
                    955:       if (ptr == cssRule)
                    956:        cssRule = ParseCSSBorderColorLeft (element, tsch, context, cssRule, css, isHTML);
                    957:       if (ptr == cssRule)
                    958:        /* rule not found */
1.86      cvs       959:        cssRule = SkipValue (cssRule);
1.82      cvs       960:       cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs       961:     }
1.1       cvs       962:   return (cssRule);
                    963: }
                    964: 
                    965: /*----------------------------------------------------------------------
1.59      cvs       966:    ParseCSSBorderBottom: parse a CSS BorderBottom
1.1       cvs       967:    attribute string.                                          
                    968:   ----------------------------------------------------------------------*/
1.79      cvs       969: static char *ParseCSSBorderBottom (Element element, PSchema tsch,
                    970:                                   PresentationContext context, char *cssRule,
                    971:                                   CSSInfoPtr css, ThotBool isHTML)
1.1       cvs       972: {
1.79      cvs       973:   char           *ptr;
1.43      cvs       974: 
1.82      cvs       975:   cssRule = SkipBlanksAndComments (cssRule);
                    976:   while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43      cvs       977:     {
                    978:       ptr = cssRule;
                    979:       cssRule = ParseCSSBorderStyleBottom (element, tsch, context, cssRule, css, isHTML);
                    980:       if (ptr == cssRule)
                    981:        cssRule = ParseCSSBorderBottomWidth (element, tsch, context, cssRule, css, isHTML);
                    982:       if (ptr == cssRule)
                    983:        cssRule = ParseCSSBorderColorBottom (element, tsch, context, cssRule, css, isHTML);
                    984:       if (ptr == cssRule)
                    985:        /* rule not found */
1.86      cvs       986:        cssRule = SkipValue (cssRule);
1.82      cvs       987:       cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs       988:     }
1.1       cvs       989:   return (cssRule);
                    990: }
                    991: 
                    992: /*----------------------------------------------------------------------
1.59      cvs       993:    ParseCSSBorderRight: parse a CSS BorderRight
1.1       cvs       994:    attribute string.                                          
                    995:   ----------------------------------------------------------------------*/
1.79      cvs       996: static char *ParseCSSBorderRight (Element element, PSchema tsch,
                    997:                                  PresentationContext context, char *cssRule,
                    998:                                  CSSInfoPtr css, ThotBool isHTML)
1.1       cvs       999: {
1.79      cvs      1000:   char            *ptr;
1.43      cvs      1001: 
1.82      cvs      1002:   cssRule = SkipBlanksAndComments (cssRule);
                   1003:   while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43      cvs      1004:     {
                   1005:       ptr = cssRule;
                   1006:       cssRule = ParseCSSBorderStyleRight (element, tsch, context, cssRule, css, isHTML);
                   1007:       if (ptr == cssRule)
                   1008:        cssRule = ParseCSSBorderRightWidth (element, tsch, context, cssRule, css, isHTML);
                   1009:       if (ptr == cssRule)
                   1010:        cssRule = ParseCSSBorderColorRight (element, tsch, context, cssRule, css, isHTML);
                   1011:       if (ptr == cssRule)
                   1012:        /* rule not found */
1.86      cvs      1013:        cssRule = SkipValue (cssRule);
1.82      cvs      1014:       cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      1015:     }
1.1       cvs      1016:   return (cssRule);
                   1017: }
                   1018: 
                   1019: /*----------------------------------------------------------------------
1.59      cvs      1020:    ParseCSSBorder: parse a CSS border        
1.42      cvs      1021:    attribute string.                                          
                   1022:   ----------------------------------------------------------------------*/
1.79      cvs      1023: static char *ParseCSSBorder (Element element, PSchema tsch,
                   1024:                             PresentationContext context, char *cssRule,
                   1025:                             CSSInfoPtr css, ThotBool isHTML)
1.42      cvs      1026: {
1.79      cvs      1027:   char *ptrT, *ptrR;
1.93      vatton   1028:   int   skippedNL;
1.42      cvs      1029: 
1.82      cvs      1030:   ptrT = SkipBlanksAndComments (cssRule);
1.42      cvs      1031:   /* First parse Border-Top */
                   1032:   ptrR = ParseCSSBorderTop (element, tsch, context, ptrT, css, isHTML);
1.82      cvs      1033:   ptrR = SkipBlanksAndComments (ptrR);
                   1034:   if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42      cvs      1035:     {
1.93      vatton   1036:       skippedNL = NewLineSkipped;
1.42      cvs      1037:       cssRule = ptrR;
                   1038:       /* apply the Border-Top to all */
                   1039:       ptrR = ParseCSSBorderRight (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   1040:       NewLineSkipped = skippedNL;
1.42      cvs      1041:       ptrR = ParseCSSBorderBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   1042:       NewLineSkipped = skippedNL;
1.42      cvs      1043:       ptrR = ParseCSSBorderLeft (element, tsch, context, ptrT, css, isHTML);
                   1044:     }
                   1045:   return (cssRule);
                   1046: }
                   1047: 
                   1048: /*----------------------------------------------------------------------
1.59      cvs      1049:    ParseCSSClear: parse a CSS clear attribute string    
1.1       cvs      1050:   ----------------------------------------------------------------------*/
1.79      cvs      1051: static char *ParseCSSClear (Element element, PSchema tsch,
                   1052:                            PresentationContext context, char *cssRule,
                   1053:                            CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1054: {
1.86      cvs      1055:   cssRule = SkipValue (cssRule);
1.1       cvs      1056:   return (cssRule);
                   1057: }
                   1058: 
                   1059: /*----------------------------------------------------------------------
1.59      cvs      1060:    ParseCSSDisplay: parse a CSS display attribute string        
1.1       cvs      1061:   ----------------------------------------------------------------------*/
1.79      cvs      1062: static char *ParseCSSDisplay (Element element, PSchema tsch,
                   1063:                              PresentationContext context, char *cssRule,
                   1064:                              CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1065: {
                   1066:    PresentationValue   pval;
                   1067: 
                   1068:    pval.typed_data.unit = STYLE_UNIT_REL;
                   1069:    pval.typed_data.real = FALSE;
1.82      cvs      1070:    cssRule = SkipBlanksAndComments (cssRule);
                   1071:    if (!strncasecmp (cssRule, "block", 5))
1.1       cvs      1072:      {
1.79      cvs      1073:        /* pval.typed_data.value = STYLE_INLINE;
1.93      vatton   1074:          TtaSetStylePresentation (PRLine, element, tsch, context, pval); */
                   1075:        cssRule = SkipWord (cssRule);
1.1       cvs      1076:      }
1.82      cvs      1077:    else if (!strncasecmp (cssRule, "inline", 6))
1.1       cvs      1078:      {
1.79      cvs      1079:        /* pval.typed_data.value = STYLE_INLINE;
1.93      vatton   1080:          TtaSetStylePresentation (PRLine, element, tsch, context, pval); */
                   1081:        cssRule = SkipWord (cssRule);
1.1       cvs      1082:      }
1.82      cvs      1083:    else if (!strncasecmp (cssRule, "none", 4))
1.1       cvs      1084:      {
                   1085:        pval.typed_data.value = STYLE_HIDE;
                   1086:        TtaSetStylePresentation (PRVisibility, element, tsch, context, pval);
                   1087:        cssRule = SkipWord (cssRule);
                   1088:      }
1.82      cvs      1089:    else if (!strncasecmp (cssRule, "list-item", 9))
1.86      cvs      1090:      cssRule = SkipValue (cssRule);
1.1       cvs      1091:    else
1.86      cvs      1092:      CSSParseError ("Invalid display value", cssRule);
1.34      cvs      1093: 
1.1       cvs      1094:    return (cssRule);
                   1095: }
                   1096: 
                   1097: /*----------------------------------------------------------------------
1.59      cvs      1098:    ParseCSSFloat: parse a CSS float attribute string    
1.1       cvs      1099:   ----------------------------------------------------------------------*/
1.79      cvs      1100: static char *ParseCSSFloat (Element element, PSchema tsch,
                   1101:                            PresentationContext context, char *cssRule,
                   1102:                            CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1103: {
1.86      cvs      1104:   cssRule = SkipValue (cssRule);
1.1       cvs      1105:   return (cssRule);
                   1106: }
                   1107: 
                   1108: /*----------------------------------------------------------------------
1.59      cvs      1109:    ParseCSSLetterSpacing: parse a CSS letter-spacing    
1.1       cvs      1110:    attribute string.                                          
                   1111:   ----------------------------------------------------------------------*/
1.79      cvs      1112: static char *ParseCSSLetterSpacing (Element element, PSchema tsch,
                   1113:                                    PresentationContext context, char *cssRule,
                   1114:                                    CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1115: {
1.86      cvs      1116:   cssRule = SkipValue (cssRule);
1.1       cvs      1117:   return (cssRule);
                   1118: }
                   1119: 
                   1120: /*----------------------------------------------------------------------
1.59      cvs      1121:    ParseCSSListStyleType: parse a CSS list-style-type
1.1       cvs      1122:    attribute string.                                          
                   1123:   ----------------------------------------------------------------------*/
1.79      cvs      1124: static char *ParseCSSListStyleType (Element element, PSchema tsch,
                   1125:                                    PresentationContext context, char *cssRule,
                   1126:                                    CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1127: {
1.86      cvs      1128:   cssRule = SkipValue (cssRule);
1.1       cvs      1129:   return (cssRule);
                   1130: }
                   1131: 
                   1132: /*----------------------------------------------------------------------
1.59      cvs      1133:    ParseCSSListStyleImage: parse a CSS list-style-image
1.1       cvs      1134:    attribute string.                                          
                   1135:   ----------------------------------------------------------------------*/
1.79      cvs      1136: static char *ParseCSSListStyleImage (Element element, PSchema tsch,
                   1137:                                     PresentationContext context, char *cssRule,
                   1138:                                     CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1139: {
1.86      cvs      1140:   cssRule = SkipValue (cssRule);
1.1       cvs      1141:   return (cssRule);
                   1142: }
                   1143: 
                   1144: /*----------------------------------------------------------------------
1.59      cvs      1145:    ParseCSSListStylePosition: parse a CSS list-style-position
1.1       cvs      1146:    attribute string.                                          
                   1147:   ----------------------------------------------------------------------*/
1.79      cvs      1148: static char *ParseCSSListStylePosition (Element element, PSchema tsch,
                   1149:                                        PresentationContext context,
                   1150:                                        char *cssRule, CSSInfoPtr css,
                   1151:                                        ThotBool isHTML)
1.1       cvs      1152: {
1.86      cvs      1153:   cssRule = SkipValue (cssRule);
1.1       cvs      1154:   return (cssRule);
                   1155: }
                   1156: 
                   1157: /*----------------------------------------------------------------------
1.59      cvs      1158:    ParseCSSListStyle: parse a CSS list-style            
1.1       cvs      1159:    attribute string.                                          
                   1160:   ----------------------------------------------------------------------*/
1.79      cvs      1161: static char *ParseCSSListStyle (Element element, PSchema tsch,
                   1162:                                PresentationContext context, char *cssRule,
                   1163:                                CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1164: {
1.86      cvs      1165:   cssRule = SkipValue (cssRule);
1.1       cvs      1166:   return (cssRule);
                   1167: }
                   1168: 
                   1169: /*----------------------------------------------------------------------
1.59      cvs      1170:    ParseCSSTextAlign: parse a CSS text-align            
1.1       cvs      1171:    attribute string.                                          
                   1172:   ----------------------------------------------------------------------*/
1.79      cvs      1173: static char *ParseCSSTextAlign (Element element, PSchema tsch,
                   1174:                                PresentationContext context, char *cssRule,
                   1175:                                CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1176: {
                   1177:    PresentationValue   align;
                   1178: 
                   1179:    align.typed_data.value = 0;
                   1180:    align.typed_data.unit = STYLE_UNIT_REL;
                   1181:    align.typed_data.real = FALSE;
                   1182: 
1.82      cvs      1183:    cssRule = SkipBlanksAndComments (cssRule);
                   1184:    if (!strncasecmp (cssRule, "left", 4))
1.1       cvs      1185:      {
                   1186:        align.typed_data.value = AdjustLeft;
                   1187:        cssRule = SkipWord (cssRule);
                   1188:      }
1.82      cvs      1189:    else if (!strncasecmp (cssRule, "right", 5))
1.1       cvs      1190:      {
                   1191:        align.typed_data.value = AdjustRight;
                   1192:        cssRule = SkipWord (cssRule);
                   1193:      }
1.82      cvs      1194:    else if (!strncasecmp (cssRule, "center", 6))
1.1       cvs      1195:      {
                   1196:        align.typed_data.value = Centered;
                   1197:        cssRule = SkipWord (cssRule);
                   1198:      }
1.82      cvs      1199:    else if (!strncasecmp (cssRule, "justify", 7))
1.1       cvs      1200:      {
1.81      cvs      1201:        align.typed_data.value = Justify;
1.1       cvs      1202:        cssRule = SkipWord (cssRule);
                   1203:      }
                   1204:    else
                   1205:      {
1.86      cvs      1206:        CSSParseError ("Invalid align value", cssRule);
1.1       cvs      1207:        return (cssRule);
                   1208:      }
                   1209: 
                   1210:    /*
                   1211:     * install the new presentation.
                   1212:     */
                   1213:    if (align.typed_data.value)
1.81      cvs      1214:      TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
1.1       cvs      1215:    return (cssRule);
                   1216: }
                   1217: 
                   1218: /*----------------------------------------------------------------------
1.59      cvs      1219:    ParseCSSTextIndent: parse a CSS text-indent          
1.1       cvs      1220:    attribute string.                                          
                   1221:   ----------------------------------------------------------------------*/
1.79      cvs      1222: static char *ParseCSSTextIndent (Element element, PSchema tsch,
                   1223:                                 PresentationContext context, char *cssRule,
                   1224:                                 CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1225: {
                   1226:    PresentationValue   pval;
                   1227: 
1.82      cvs      1228:    cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      1229:    cssRule = ParseCSSUnit (cssRule, &pval);
                   1230:    if (pval.typed_data.unit == STYLE_UNIT_INVALID)
                   1231:      return (cssRule);
                   1232:    /* install the attribute */
                   1233:    TtaSetStylePresentation (PRIndent, element, tsch, context, pval);
                   1234:    return (cssRule);
                   1235: }
                   1236: 
                   1237: /*----------------------------------------------------------------------
1.59      cvs      1238:    ParseCSSTextTransform: parse a CSS text-transform    
1.1       cvs      1239:    attribute string.                                          
                   1240:   ----------------------------------------------------------------------*/
1.79      cvs      1241: static char *ParseCSSTextTransform (Element element, PSchema tsch,
                   1242:                                    PresentationContext context, char *cssRule,
                   1243:                                    CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1244: {
1.86      cvs      1245:   cssRule = SkipValue (cssRule);
1.1       cvs      1246:   return (cssRule);
                   1247: }
                   1248: 
                   1249: /*----------------------------------------------------------------------
1.59      cvs      1250:    ParseCSSVerticalAlign: parse a CSS vertical-align    
1.1       cvs      1251:    attribute string.                                          
                   1252:   ----------------------------------------------------------------------*/
1.79      cvs      1253: static char *ParseCSSVerticalAlign (Element element, PSchema tsch,
                   1254:                                    PresentationContext context, char *cssRule,
                   1255:                                    CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1256: {
1.86      cvs      1257:   cssRule = SkipValue (cssRule);
1.1       cvs      1258:   return (cssRule);
                   1259: }
                   1260: 
                   1261: /*----------------------------------------------------------------------
1.59      cvs      1262:    ParseCSSWhiteSpace: parse a CSS white-space          
1.1       cvs      1263:    attribute string.                                          
                   1264:   ----------------------------------------------------------------------*/
1.79      cvs      1265: static char *ParseCSSWhiteSpace (Element element, PSchema tsch,
                   1266:                                 PresentationContext context, char *cssRule,
                   1267:                                 CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1268: {
1.82      cvs      1269:    cssRule = SkipBlanksAndComments (cssRule);
                   1270:    if (!strncasecmp (cssRule, "normal", 6))
1.1       cvs      1271:      cssRule = SkipWord (cssRule);
1.82      cvs      1272:    else if (!strncasecmp (cssRule, "pre", 3))
1.1       cvs      1273:      cssRule = SkipWord (cssRule);
                   1274:    else
                   1275:      return (cssRule);
                   1276:    return (cssRule);
                   1277: }
                   1278: 
                   1279: /*----------------------------------------------------------------------
1.59      cvs      1280:    ParseCSSWordSpacing: parse a CSS word-spacing        
1.1       cvs      1281:    attribute string.                                          
                   1282:   ----------------------------------------------------------------------*/
1.79      cvs      1283: static char *ParseCSSWordSpacing (Element element, PSchema tsch,
                   1284:                                  PresentationContext context, char *cssRule,
                   1285:                                  CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1286: {
1.86      cvs      1287:   cssRule = SkipValue (cssRule);
1.1       cvs      1288:   return (cssRule);
                   1289: }
                   1290: 
                   1291: /*----------------------------------------------------------------------
1.59      cvs      1292:    ParseCSSLineSpacing: parse a CSS font leading string 
1.25      cvs      1293:    we expect the input string describing the attribute to be     
                   1294:    value% or value                                               
                   1295:   ----------------------------------------------------------------------*/
1.79      cvs      1296: static char *ParseCSSLineSpacing (Element element, PSchema tsch,
                   1297:                                  PresentationContext context, char *cssRule,
                   1298:                                  CSSInfoPtr css, ThotBool isHTML)
1.25      cvs      1299: {
                   1300:    PresentationValue   lead;
                   1301: 
                   1302:    cssRule = ParseCSSUnit (cssRule, &lead);
1.93      vatton   1303:    if (lead.typed_data.unit != STYLE_UNIT_INVALID)
                   1304:      /* install the new presentation */
                   1305:      TtaSetStylePresentation (PRLineSpacing, element, tsch, context, lead);
1.25      cvs      1306:    return (cssRule);
                   1307: }
                   1308: 
                   1309: /*----------------------------------------------------------------------
1.59      cvs      1310:    ParseCSSFontSize: parse a CSS font size attr string  
1.1       cvs      1311:    we expect the input string describing the attribute to be     
                   1312:    xx-small, x-small, small, medium, large, x-large, xx-large      
                   1313:    or an absolute size, or an imcrement relative to the parent     
                   1314:   ----------------------------------------------------------------------*/
1.79      cvs      1315: static char *ParseCSSFontSize (Element element, PSchema tsch,
                   1316:                               PresentationContext context, char *cssRule,
                   1317:                               CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1318: {
                   1319:    PresentationValue   pval;
1.79      cvs      1320:    char               *ptr = NULL;
1.14      cvs      1321:    ThotBool           real;
1.1       cvs      1322: 
                   1323:    pval.typed_data.real = FALSE;
1.82      cvs      1324:    cssRule = SkipBlanksAndComments (cssRule);
                   1325:    if (!strncasecmp (cssRule, "larger", 6))
1.1       cvs      1326:      {
                   1327:        pval.typed_data.unit = STYLE_UNIT_PERCENT;
                   1328:        pval.typed_data.value = 130;
                   1329:        cssRule = SkipWord (cssRule);
                   1330:      }
1.82      cvs      1331:    else if (!strncasecmp (cssRule, "smaller", 7))
1.1       cvs      1332:      {
                   1333:        pval.typed_data.unit = STYLE_UNIT_PERCENT;
                   1334:        pval.typed_data.value = 80;
                   1335:        cssRule = SkipWord (cssRule);
                   1336:      }
1.82      cvs      1337:    else if (!strncasecmp (cssRule, "xx-small", 8))
1.1       cvs      1338:      {
                   1339:        pval.typed_data.unit = STYLE_UNIT_REL;
                   1340:        pval.typed_data.value = 1;
                   1341:        cssRule = SkipWord (cssRule);
                   1342:      }
1.82      cvs      1343:    else if (!strncasecmp (cssRule, "x-small", 7))
1.1       cvs      1344:      {
                   1345:        pval.typed_data.unit = STYLE_UNIT_REL;
                   1346:        pval.typed_data.value = 2;
                   1347:        cssRule = SkipWord (cssRule);
                   1348:      }
1.82      cvs      1349:    else if (!strncasecmp (cssRule, "small", 5))
1.1       cvs      1350:      {
                   1351:        pval.typed_data.unit = STYLE_UNIT_REL;
                   1352:        pval.typed_data.value = 3;
                   1353:        cssRule = SkipWord (cssRule);
                   1354:      }
1.82      cvs      1355:    else if (!strncasecmp (cssRule, "medium", 6))
1.1       cvs      1356:      {
                   1357:        pval.typed_data.unit = STYLE_UNIT_REL;
                   1358:        pval.typed_data.value = 4;
                   1359:        cssRule = SkipWord (cssRule);
                   1360:      }
1.82      cvs      1361:    else if (!strncasecmp (cssRule, "large", 5))
1.1       cvs      1362:      {
                   1363:        pval.typed_data.unit = STYLE_UNIT_REL;
                   1364:        pval.typed_data.value = 5;
                   1365:        cssRule = SkipWord (cssRule);
                   1366:      }
1.82      cvs      1367:    else if (!strncasecmp (cssRule, "x-large", 7))
1.1       cvs      1368:      {
                   1369:        pval.typed_data.unit = STYLE_UNIT_REL;
                   1370:        pval.typed_data.value = 6;
                   1371:        cssRule = SkipWord (cssRule);
                   1372:      }
1.82      cvs      1373:    else if (!strncasecmp (cssRule, "xx-large", 8))
1.1       cvs      1374:      {
                   1375:        pval.typed_data.unit = STYLE_UNIT_REL;
                   1376:        pval.typed_data.value = 7;
                   1377:        cssRule = SkipWord (cssRule);
                   1378:      }
                   1379:    else
                   1380:      {
1.25      cvs      1381:        /* look for a '/' within the current cssRule */
1.82      cvs      1382:        ptr = strchr (cssRule, '/');
1.25      cvs      1383:        if (ptr != NULL)
                   1384:         {
                   1385:           /* keep the line spacing rule */
1.82      cvs      1386:           ptr[0] = EOS;
1.25      cvs      1387:           ptr = &ptr[1];
                   1388:         }
1.1       cvs      1389:        cssRule = ParseCSSUnit (cssRule, &pval);
                   1390:        if (pval.typed_data.unit == STYLE_UNIT_INVALID ||
                   1391:            pval.typed_data.value < 0)
                   1392:         return (cssRule);
                   1393:        if (pval.typed_data.unit == STYLE_UNIT_REL && pval.typed_data.value > 0)
                   1394:         /* CSS relative sizes have to be higher than Thot ones */
                   1395:         pval.typed_data.value += 1;
                   1396:        else 
                   1397:         {
                   1398:           real = pval.typed_data.real;
                   1399:           if (pval.typed_data.unit == STYLE_UNIT_EM)
                   1400:             {
                   1401:               if (real)
                   1402:                 {
                   1403:                   pval.typed_data.value /= 10;
1.11      cvs      1404:                   pval.typed_data.real = FALSE;
1.1       cvs      1405:                   real = FALSE;
                   1406:                 }
                   1407:               else
                   1408:                 pval.typed_data.value *= 100;
                   1409:               pval.typed_data.unit = STYLE_UNIT_PERCENT;
                   1410:             }
                   1411:         }
1.25      cvs      1412: 
1.1       cvs      1413:      }
                   1414: 
1.25      cvs      1415:    /* install the presentation style */
1.1       cvs      1416:    TtaSetStylePresentation (PRSize, element, tsch, context, pval);
1.25      cvs      1417: 
                   1418:    if (ptr != NULL)
                   1419:      cssRule = ParseCSSLineSpacing (element, tsch, context, ptr, css, isHTML);
1.1       cvs      1420:    return (cssRule);
                   1421: }
                   1422: 
                   1423: /*----------------------------------------------------------------------
1.59      cvs      1424:    ParseCSSFontFamily: parse a CSS font family string   
1.1       cvs      1425:    we expect the input string describing the attribute to be     
                   1426:    a common generic font style name                                
                   1427:   ----------------------------------------------------------------------*/
1.79      cvs      1428: static char *ParseCSSFontFamily (Element element, PSchema tsch,
                   1429:                                 PresentationContext context, char *cssRule,
                   1430:                                 CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1431: {
                   1432:   PresentationValue   font;
1.79      cvs      1433:   char              quoteChar;
1.1       cvs      1434: 
                   1435:   font.typed_data.value = 0;
                   1436:   font.typed_data.unit = STYLE_UNIT_REL;
                   1437:   font.typed_data.real = FALSE;
1.82      cvs      1438:   cssRule = SkipBlanksAndComments (cssRule);
                   1439:   if (*cssRule == '"' || *cssRule == '\'')
1.1       cvs      1440:      {
                   1441:      quoteChar = *cssRule;
                   1442:      cssRule++;
                   1443:      }
                   1444:   else
1.82      cvs      1445:      quoteChar = EOS;
1.1       cvs      1446: 
1.92      cvs      1447:   if (!strncasecmp (cssRule, "times", 5) &&
                   1448:       (quoteChar == EOS || quoteChar == cssRule[5]))
1.86      cvs      1449:     {
1.1       cvs      1450:       font.typed_data.value = STYLE_FONT_TIMES;
1.86      cvs      1451:       cssRule += 5;
                   1452:     }
1.92      cvs      1453:   else if (!strncasecmp (cssRule, "serif", 5) &&
                   1454:       (quoteChar == EOS || quoteChar == cssRule[5]))
1.86      cvs      1455:     {
1.1       cvs      1456:       font.typed_data.value = STYLE_FONT_TIMES;
1.86      cvs      1457:       cssRule += 5;
1.92      cvs      1458:       if (quoteChar != EOS)
                   1459:        cssRule++;
1.86      cvs      1460:     }
1.92      cvs      1461:   else if (!strncasecmp (cssRule, "helvetica", 9) &&
                   1462:       (quoteChar == EOS || quoteChar == cssRule[9]))
1.86      cvs      1463:     {
                   1464:      font.typed_data.value = STYLE_FONT_HELVETICA;
                   1465:       cssRule += 9;
1.92      cvs      1466:       if (quoteChar != EOS)
                   1467:        cssRule++;
1.86      cvs      1468:     }
1.92      cvs      1469:   else if (!strncasecmp (cssRule, "verdana", 7) &&
                   1470:       (quoteChar == EOS || quoteChar == cssRule[7]))
1.86      cvs      1471:     {
1.1       cvs      1472:       font.typed_data.value = STYLE_FONT_HELVETICA;
1.86      cvs      1473:       cssRule += 7;
1.92      cvs      1474:       if (quoteChar != EOS)
                   1475:        cssRule++;
1.86      cvs      1476:     }
1.92      cvs      1477:   else if (!strncasecmp (cssRule, "sans-serif", 10) &&
                   1478:       (quoteChar == EOS || quoteChar == cssRule[10]))
1.86      cvs      1479:     {
1.1       cvs      1480:       font.typed_data.value = STYLE_FONT_HELVETICA;
1.86      cvs      1481:       cssRule += 10;
1.92      cvs      1482:       if (quoteChar != EOS)
                   1483:        cssRule++;
1.86      cvs      1484:     }
1.92      cvs      1485:   else if (!strncasecmp (cssRule, "courier", 7) &&
                   1486:       (quoteChar == EOS || quoteChar == cssRule[7]))
1.86      cvs      1487:     {
1.1       cvs      1488:       font.typed_data.value = STYLE_FONT_COURIER;
1.86      cvs      1489:       cssRule += 7;
1.92      cvs      1490:       if (quoteChar != EOS)
                   1491:        cssRule++;
1.86      cvs      1492:     }
1.92      cvs      1493:   else if (!strncasecmp (cssRule, "monospace", 9) &&
                   1494:       (quoteChar == EOS || quoteChar == cssRule[9]))
1.86      cvs      1495:     {
1.1       cvs      1496:       font.typed_data.value = STYLE_FONT_COURIER;
1.86      cvs      1497:       cssRule += 9;
1.92      cvs      1498:       if (quoteChar != EOS)
                   1499:        cssRule++;
1.86      cvs      1500:     }
1.1       cvs      1501:   else
                   1502:     /* unknown font name.  Skip it */
                   1503:     {
1.92      cvs      1504:       if (quoteChar != EOS)
1.54      cvs      1505:          cssRule = SkipQuotedString (cssRule, quoteChar);
1.86      cvs      1506:       else
1.1       cvs      1507:          cssRule = SkipWord (cssRule);
1.82      cvs      1508:       cssRule = SkipBlanksAndComments (cssRule);
                   1509:       if (*cssRule == ',')
1.1       cvs      1510:        {
1.86      cvs      1511:          cssRule++;
                   1512:          cssRule = ParseCSSFontFamily (element, tsch, context, cssRule, css, isHTML);
                   1513:          return (cssRule);
1.1       cvs      1514:        }
                   1515:     }
                   1516: 
                   1517:   if (font.typed_data.value != 0)
                   1518:      {
1.93      vatton   1519:        cssRule = SkipBlanksAndComments (cssRule);
                   1520:        cssRule = SkipValue (cssRule);
                   1521:        /* install the new presentation */
                   1522:        TtaSetStylePresentation (PRFont, element, tsch, context, font);
1.1       cvs      1523:      }
                   1524:   return (cssRule);
                   1525: }
                   1526: 
                   1527: /*----------------------------------------------------------------------
1.59      cvs      1528:    ParseCSSFontWeight: parse a CSS font weight string   
1.1       cvs      1529:    we expect the input string describing the attribute to be     
1.20      cvs      1530:    normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.1       cvs      1531:   ----------------------------------------------------------------------*/
1.79      cvs      1532: static char *ParseCSSFontWeight (Element element, PSchema tsch,
                   1533:                                 PresentationContext context, char *cssRule,
                   1534:                                 CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1535: {
1.20      cvs      1536:    PresentationValue   weight;
1.1       cvs      1537: 
                   1538:    weight.typed_data.value = 0;
                   1539:    weight.typed_data.unit = STYLE_UNIT_REL;
                   1540:    weight.typed_data.real = FALSE;
1.82      cvs      1541:    cssRule = SkipBlanksAndComments (cssRule);
                   1542:    if (!strncasecmp (cssRule, "100", 3) && !isalpha (cssRule[3]))
1.1       cvs      1543:      {
                   1544:        weight.typed_data.value = -3;
                   1545:        cssRule = SkipWord (cssRule);
                   1546:      }
1.82      cvs      1547:    else if (!strncasecmp (cssRule, "200", 3) && !isalpha (cssRule[3]))
1.1       cvs      1548:      {
                   1549:        weight.typed_data.value = -2;
                   1550:        cssRule = SkipWord (cssRule);
                   1551:      }
1.82      cvs      1552:    else if (!strncasecmp (cssRule, "300", 3) && ! isalpha(cssRule[3]))
1.1       cvs      1553:      {
                   1554:        weight.typed_data.value = -1;
                   1555:        cssRule = SkipWord (cssRule);
                   1556:      }
1.82      cvs      1557:    else if (!strncasecmp (cssRule, "normal", 6) || (!strncasecmp (cssRule, "400", 3) && !isalpha (cssRule[3])))
1.1       cvs      1558:      {
                   1559:        weight.typed_data.value = 0;
                   1560:        cssRule = SkipWord (cssRule);
                   1561:      }
1.82      cvs      1562:    else if (!strncasecmp (cssRule, "500", 3) && !isalpha (cssRule[3]))
1.1       cvs      1563:      {
                   1564:        weight.typed_data.value = +1;
                   1565:        cssRule = SkipWord (cssRule);
                   1566:      }
1.82      cvs      1567:    else if (!strncasecmp (cssRule, "600", 3) && !isalpha (cssRule[3]))
1.1       cvs      1568:      {
                   1569:        weight.typed_data.value = +2;
                   1570:        cssRule = SkipWord (cssRule);
                   1571:      }
1.82      cvs      1572:    else if (!strncasecmp (cssRule, "bold", 4) || (!strncasecmp (cssRule, "700", 3) && !isalpha (cssRule[3])))
1.1       cvs      1573:      {
                   1574:        weight.typed_data.value = +3;
                   1575:        cssRule = SkipWord (cssRule);
                   1576:      }
1.82      cvs      1577:    else if (!strncasecmp (cssRule, "800", 3) && !isalpha (cssRule[3]))
1.1       cvs      1578:      {
                   1579:        weight.typed_data.value = +4;
                   1580:        cssRule = SkipWord (cssRule);
                   1581:      }
1.82      cvs      1582:    else if (!strncasecmp (cssRule, "900", 3) && !isalpha (cssRule[3]))
1.1       cvs      1583:      {
                   1584:        weight.typed_data.value = +5;
                   1585:        cssRule = SkipWord (cssRule);
                   1586:      }
1.82      cvs      1587:    else if (!strncasecmp (cssRule, "inherit", 7) || !strncasecmp (cssRule, "bolder", 6) || !strncasecmp (cssRule, "lighter", 7))
1.1       cvs      1588:      {
                   1589:      /* not implemented */
                   1590:      cssRule = SkipWord (cssRule);
                   1591:      return (cssRule);
                   1592:      }
                   1593:    else
                   1594:      return (cssRule);
                   1595: 
                   1596:    /*
1.20      cvs      1597:     * Here we have to reduce since only two font weight values are supported
1.1       cvs      1598:     * by the Thot presentation API.
                   1599:     */
1.20      cvs      1600:     if (weight.typed_data.value > 0)
                   1601:        weight.typed_data.value = STYLE_WEIGHT_BOLD;
                   1602:     else
                   1603:        weight.typed_data.value = STYLE_WEIGHT_NORMAL;
1.1       cvs      1604: 
                   1605:    /* install the new presentation */
1.21      cvs      1606:    TtaSetStylePresentation (PRWeight, element, tsch, context, weight);
1.1       cvs      1607:    return (cssRule);
                   1608: }
                   1609: 
                   1610: /*----------------------------------------------------------------------
1.59      cvs      1611:    ParseCSSFontVariant: parse a CSS font variant string     
1.1       cvs      1612:    we expect the input string describing the attribute to be     
                   1613:    normal or small-caps
                   1614:   ----------------------------------------------------------------------*/
1.79      cvs      1615: static char *ParseCSSFontVariant (Element element, PSchema tsch,
                   1616:                                  PresentationContext context, char *cssRule,
                   1617:                                  CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1618: {
                   1619:    PresentationValue   style;
                   1620: 
                   1621:    style.typed_data.value = 0;
                   1622:    style.typed_data.unit = STYLE_UNIT_REL;
                   1623:    style.typed_data.real = FALSE;
1.82      cvs      1624:    cssRule = SkipBlanksAndComments (cssRule);
                   1625:    if (!strncasecmp (cssRule, "small-caps", 10))
1.1       cvs      1626:      {
                   1627:        /* Not supported yet */
                   1628:        cssRule = SkipWord (cssRule);
                   1629:      }
1.82      cvs      1630:    else if (!strncasecmp (cssRule, "normal", 6))
1.1       cvs      1631:      {
                   1632:        /* Not supported yet */
                   1633:        cssRule = SkipWord (cssRule);
                   1634:      }
1.82      cvs      1635:    else if (!strncasecmp (cssRule, "inherit", 7))
1.1       cvs      1636:      {
                   1637:        /* Not supported yet */
                   1638:        cssRule = SkipWord (cssRule);
                   1639:      }
                   1640:    else
                   1641:        return (cssRule);
                   1642: 
                   1643:    return (cssRule);
                   1644: }
                   1645: 
                   1646: 
                   1647: /*----------------------------------------------------------------------
1.59      cvs      1648:    ParseCSSFontStyle: parse a CSS font style string     
1.1       cvs      1649:    we expect the input string describing the attribute to be     
                   1650:    italic, oblique or normal                         
                   1651:   ----------------------------------------------------------------------*/
1.79      cvs      1652: static char *ParseCSSFontStyle (Element element, PSchema tsch,
                   1653:                                PresentationContext context, char *cssRule,
                   1654:                                CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1655: {
                   1656:    PresentationValue   style;
                   1657:    PresentationValue   size;
                   1658: 
                   1659:    style.typed_data.value = 0;
                   1660:    style.typed_data.unit = STYLE_UNIT_REL;
                   1661:    style.typed_data.real = FALSE;
                   1662:    size.typed_data.value = 0;
                   1663:    size.typed_data.unit = STYLE_UNIT_REL;
                   1664:    size.typed_data.real = FALSE;
1.82      cvs      1665:    cssRule = SkipBlanksAndComments (cssRule);
                   1666:    if (!strncasecmp (cssRule, "italic", 6))
1.1       cvs      1667:      {
                   1668:        style.typed_data.value = STYLE_FONT_ITALICS;
                   1669:        cssRule = SkipWord (cssRule);
                   1670:      }
1.82      cvs      1671:    else if (!strncasecmp (cssRule, "oblique", 7))
1.1       cvs      1672:      {
                   1673:        style.typed_data.value = STYLE_FONT_OBLIQUE;
                   1674:        cssRule = SkipWord (cssRule);
                   1675:      }
1.82      cvs      1676:    else if (!strncasecmp (cssRule, "normal", 6))
1.1       cvs      1677:      {
                   1678:        style.typed_data.value = STYLE_FONT_ROMAN;
                   1679:        cssRule = SkipWord (cssRule);
                   1680:      }
                   1681:    else
                   1682:      {
                   1683:        /* invalid font style */
                   1684:        return (cssRule);
                   1685:      }
                   1686: 
                   1687:    /*
                   1688:     * install the new presentation.
                   1689:     */
                   1690:    if (style.typed_data.value != 0)
1.20      cvs      1691:         TtaSetStylePresentation (PRStyle, element, tsch, context, style);
1.1       cvs      1692:    if (size.typed_data.value != 0)
                   1693:      {
                   1694:        PresentationValue   previous_size;
                   1695: 
                   1696:        if (!TtaGetStylePresentation (PRSize, element, tsch, context, &previous_size))
                   1697:          {
                   1698:             /* !!!!!!!!!!!!!!!!!!!!!!!! Unite + relatif !!!!!!!!!!!!!!!! */
                   1699:             size.typed_data.value += previous_size.typed_data.value;
                   1700:             TtaSetStylePresentation (PRSize, element, tsch, context, size);
                   1701:          }
                   1702:        else
                   1703:          {
                   1704:             size.typed_data.value = 10;
                   1705:             TtaSetStylePresentation (PRSize, element, tsch, context, size);
                   1706:          }
                   1707:      }
                   1708:    return (cssRule);
                   1709: }
                   1710: 
                   1711: /*----------------------------------------------------------------------
1.59      cvs      1712:   ParseCSSFont: parse a CSS font attribute string
                   1713:   we expect the input string describing the attribute to be
                   1714:   !!!!!!                                  
1.1       cvs      1715:   ----------------------------------------------------------------------*/
1.79      cvs      1716: static char *ParseCSSFont (Element element, PSchema tsch,
                   1717:                           PresentationContext context, char *cssRule,
                   1718:                           CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1719: {
1.79      cvs      1720:   char           *ptr;
1.93      vatton   1721:   int             skippedNL;
1.1       cvs      1722: 
1.82      cvs      1723:   cssRule = SkipBlanksAndComments (cssRule);
                   1724:   if (!strncasecmp (cssRule, "caption", 7))
1.1       cvs      1725:     ;
1.82      cvs      1726:   else if (!strncasecmp (cssRule, "icon", 4))
1.1       cvs      1727:     ;
1.82      cvs      1728:   else if (!strncasecmp (cssRule, "menu", 4))
1.1       cvs      1729:     ;
1.82      cvs      1730:   else if (!strncasecmp (cssRule, "message-box", 11))
1.1       cvs      1731:     ;
1.82      cvs      1732:   else if (!strncasecmp (cssRule, "small-caption", 13))
1.1       cvs      1733:     ;
1.82      cvs      1734:   else if (!strncasecmp (cssRule, "status-bar", 10))
1.1       cvs      1735:     ;
                   1736:   else
1.43      cvs      1737:     {
1.82      cvs      1738:       while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43      cvs      1739:        {
1.72      cvs      1740:          ptr = cssRule;
1.93      vatton   1741:          skippedNL = NewLineSkipped;
1.72      cvs      1742:          cssRule = ParseCSSFontStyle (element, tsch, context, cssRule, css, isHTML);
                   1743:          if (ptr == cssRule)
1.93      vatton   1744:            {
                   1745:              NewLineSkipped = skippedNL;
                   1746:              cssRule = ParseCSSFontVariant (element, tsch, context, cssRule, css, isHTML);
                   1747:            }
1.72      cvs      1748:          if (ptr == cssRule)
1.93      vatton   1749:            {
                   1750:              NewLineSkipped = skippedNL;
                   1751:              cssRule = ParseCSSFontWeight (element, tsch, context, cssRule, css, isHTML);
                   1752:            }
1.72      cvs      1753:          if (ptr == cssRule)
1.93      vatton   1754:            {
                   1755:              NewLineSkipped = skippedNL;
                   1756:              cssRule = ParseCSSFontSize (element, tsch, context, cssRule, css, isHTML);
                   1757:            }
1.72      cvs      1758:          if (ptr == cssRule)
1.93      vatton   1759:            {
                   1760:              NewLineSkipped = skippedNL;
                   1761:              cssRule = ParseCSSFontFamily (element, tsch, context, cssRule, css, isHTML);
                   1762:            }
1.82      cvs      1763:          cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      1764:        }
                   1765:     }
                   1766:   return (cssRule);
1.1       cvs      1767: }
                   1768: 
                   1769: /*----------------------------------------------------------------------
1.59      cvs      1770:   ParseCSSTextDecoration: parse a CSS text decor string   
                   1771:   we expect the input string describing the attribute to be     
                   1772:   underline, overline, line-through, box, shadowbox, box3d,       
                   1773:   cartouche, blink or none
1.1       cvs      1774:   ----------------------------------------------------------------------*/
1.79      cvs      1775: static char *ParseCSSTextDecoration (Element element, PSchema tsch,
                   1776:                                     PresentationContext context, char *cssRule,
                   1777:                                     CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1778: {
                   1779:    PresentationValue   decor;
                   1780: 
                   1781:    decor.typed_data.value = 0;
                   1782:    decor.typed_data.unit = STYLE_UNIT_REL;
                   1783:    decor.typed_data.real = FALSE;
1.82      cvs      1784:    cssRule = SkipBlanksAndComments (cssRule);
                   1785:    if (!strncasecmp (cssRule, "underline", strlen ("underline")))
1.1       cvs      1786:      {
                   1787:        decor.typed_data.value = Underline;
                   1788:        cssRule = SkipWord (cssRule);
                   1789:      }
1.82      cvs      1790:    else if (!strncasecmp (cssRule, "overline", strlen ("overline")))
1.1       cvs      1791:      {
                   1792:        decor.typed_data.value = Overline;
                   1793:        cssRule = SkipWord (cssRule);
                   1794:      }
1.82      cvs      1795:    else if (!strncasecmp (cssRule, "line-through", strlen ("line-through")))
1.1       cvs      1796:      {
                   1797:        decor.typed_data.value = CrossOut;
                   1798:        cssRule = SkipWord (cssRule);
                   1799:      }
1.82      cvs      1800:    else if (!strncasecmp (cssRule, "box", strlen ("box")))
1.1       cvs      1801:      {
                   1802:        /* the box text-decoration attribute is not yet supported */
                   1803:        cssRule = SkipWord (cssRule);
                   1804:      }
1.82      cvs      1805:    else if (!strncasecmp (cssRule, "boxshadow", strlen ("boxshadow")))
1.1       cvs      1806:      {
                   1807:        /* the boxshadow text-decoration attribute is not yet supported */
                   1808:        cssRule = SkipWord (cssRule);
                   1809:      }
1.82      cvs      1810:    else if (!strncasecmp (cssRule, "box3d", strlen ("box3d")))
1.1       cvs      1811:      {
                   1812:        /* the box3d text-decoration attribute is not yet supported */
                   1813:        cssRule = SkipWord (cssRule);
                   1814:      }
1.82      cvs      1815:    else if (!strncasecmp (cssRule, "cartouche", strlen ("cartouche")))
1.1       cvs      1816:      {
                   1817:        /*the cartouche text-decoration attribute is not yet supported */
                   1818:        cssRule = SkipWord (cssRule);
                   1819:      }
1.82      cvs      1820:    else if (!strncasecmp (cssRule, "blink", strlen ("blink")))
1.1       cvs      1821:      {
                   1822:        /*the blink text-decoration attribute will not be supported */
                   1823:        cssRule = SkipWord (cssRule);
                   1824:      }
1.82      cvs      1825:    else if (!strncasecmp (cssRule, "none", strlen ("none")))
1.1       cvs      1826:      {
                   1827:        decor.typed_data.value = NoUnderline;
                   1828:        cssRule = SkipWord (cssRule);
                   1829:      }
                   1830:    else
                   1831:      {
1.86      cvs      1832:        CSSParseError ("Invalid text decoration", cssRule);
1.1       cvs      1833:        return (cssRule);
                   1834:      }
                   1835: 
                   1836:    /*
                   1837:     * install the new presentation.
                   1838:     */
                   1839:    if (decor.typed_data.value)
                   1840:      {
                   1841:        TtaSetStylePresentation (PRUnderline, element, tsch, context, decor);
                   1842:      }
                   1843:    return (cssRule);
                   1844: }
                   1845: 
                   1846: /*----------------------------------------------------------------------
1.59      cvs      1847:    ParseCSSHeight: parse a CSS height attribute
1.1       cvs      1848:   ----------------------------------------------------------------------*/
1.79      cvs      1849: static char *ParseCSSHeight (Element element, PSchema tsch,
1.93      vatton   1850:                             PresentationContext context, char *cssRule,
                   1851:                             CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      1852: {
1.93      vatton   1853:    PresentationValue   val;
                   1854: 
1.82      cvs      1855:    cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      1856:    /* first parse the attribute string */
1.82      cvs      1857:    if (!strcasecmp (cssRule, "auto"))
1.93      vatton   1858:      cssRule = SkipWord (cssRule);
                   1859:    else
1.1       cvs      1860:      {
1.93      vatton   1861:        cssRule = ParseCSSUnit (cssRule, &val);
                   1862:        if (val.typed_data.unit != STYLE_UNIT_INVALID)
                   1863:         /* install the new presentation */
                   1864:         TtaSetStylePresentation (PRHeight, element, tsch, context, val);
1.1       cvs      1865:      }
                   1866:    return (cssRule);
                   1867: }
                   1868: 
                   1869: /*----------------------------------------------------------------------
1.59      cvs      1870:    ParseCSSWidth: parse a CSS width attribute
1.1       cvs      1871:   ----------------------------------------------------------------------*/
1.79      cvs      1872: static char *ParseCSSWidth (Element element, PSchema tsch,
1.78      cvs      1873:                              PresentationContext context,
1.79      cvs      1874:                              char *cssRule, CSSInfoPtr css,
1.78      cvs      1875:                              ThotBool isHTML)
1.1       cvs      1876: {
1.93      vatton   1877:    PresentationValue   val;
                   1878: 
1.82      cvs      1879:    cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      1880:    /* first parse the attribute string */
1.82      cvs      1881:    if (!strcasecmp (cssRule, "auto"))
1.93      vatton   1882:      cssRule = SkipWord (cssRule);
                   1883:    else
1.1       cvs      1884:      {
1.93      vatton   1885:        cssRule = ParseCSSUnit (cssRule, &val);
                   1886:        if (val.typed_data.unit != STYLE_UNIT_INVALID)
                   1887:         /* install the new presentation */
                   1888:         TtaSetStylePresentation (PRWidth, element, tsch, context, val);
1.1       cvs      1889:      }
                   1890:    return (cssRule);
                   1891: }
                   1892: 
                   1893: /*----------------------------------------------------------------------
1.59      cvs      1894:    ParseCSSMarginTop: parse a CSS margin-top attribute
1.1       cvs      1895:   ----------------------------------------------------------------------*/
1.79      cvs      1896: static char *ParseCSSMarginTop (Element element, PSchema tsch,
1.78      cvs      1897:                                  PresentationContext context,
1.79      cvs      1898:                                  char *cssRule, CSSInfoPtr css,
1.78      cvs      1899:                                  ThotBool isHTML)
1.1       cvs      1900: {
                   1901:   PresentationValue   margin;
                   1902:   
1.82      cvs      1903:   cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      1904:   /* first parse the attribute string */
                   1905:   cssRule = ParseCSSUnit (cssRule, &margin);
1.43      cvs      1906:   if (margin.typed_data.unit != STYLE_UNIT_INVALID)
1.1       cvs      1907:     {
1.40      cvs      1908:       TtaSetStylePresentation (PRMarginTop, element, tsch, context, margin);
1.1       cvs      1909:       if (margin.typed_data.value < 0)
                   1910:        TtaSetStylePresentation (PRVertOverflow, element, tsch, context, margin);
                   1911:     }
                   1912:   return (cssRule);
                   1913: }
                   1914: 
                   1915: /*----------------------------------------------------------------------
1.59      cvs      1916:   ParseCSSMarginBottom: parse a CSS margin-bottom attribute
1.1       cvs      1917:   ----------------------------------------------------------------------*/
1.79      cvs      1918: static char *ParseCSSMarginBottom (Element element, PSchema tsch,
1.78      cvs      1919:                                     PresentationContext context,
1.79      cvs      1920:                                     char *cssRule, CSSInfoPtr css,
1.78      cvs      1921:                                     ThotBool isHTML)
1.1       cvs      1922: {
                   1923:   PresentationValue   margin;
                   1924:   
1.82      cvs      1925:   cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      1926:   /* first parse the attribute string */
                   1927:   cssRule = ParseCSSUnit (cssRule, &margin);
1.43      cvs      1928:   if (margin.typed_data.unit != STYLE_UNIT_INVALID)
                   1929:     TtaSetStylePresentation (PRMarginBottom, element, tsch, context, margin);
1.1       cvs      1930:   return (cssRule);
                   1931: }
                   1932: 
                   1933: /*----------------------------------------------------------------------
1.59      cvs      1934:   ParseCSSMarginLeft: parse a CSS margin-left attribute string
1.1       cvs      1935:   ----------------------------------------------------------------------*/
1.79      cvs      1936: static char *ParseCSSMarginLeft (Element element, PSchema tsch,
1.78      cvs      1937:                                   PresentationContext context,
1.79      cvs      1938:                                   char *cssRule, CSSInfoPtr css,
1.78      cvs      1939:                                   ThotBool isHTML)
1.1       cvs      1940: {
                   1941:   PresentationValue   margin;
                   1942:   
1.82      cvs      1943:   cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      1944:   /* first parse the attribute string */
                   1945:   cssRule = ParseCSSUnit (cssRule, &margin);
1.43      cvs      1946:   if (margin.typed_data.unit != STYLE_UNIT_INVALID)
1.1       cvs      1947:     {
1.40      cvs      1948:       TtaSetStylePresentation (PRMarginLeft, element, tsch, context, margin);
1.1       cvs      1949:       if (margin.typed_data.value < 0)
                   1950:        TtaSetStylePresentation (PRHorizOverflow, element, tsch, context, margin);
                   1951:     }
                   1952:   return (cssRule);
                   1953: }
                   1954: 
                   1955: /*----------------------------------------------------------------------
1.59      cvs      1956:   ParseCSSMarginRight: parse a CSS margin-right attribute string
1.1       cvs      1957:   ----------------------------------------------------------------------*/
1.79      cvs      1958: static char *ParseCSSMarginRight (Element element, PSchema tsch,
1.78      cvs      1959:                                    PresentationContext context,
1.79      cvs      1960:                                    char *cssRule, CSSInfoPtr css,
1.78      cvs      1961:                                    ThotBool isHTML)
1.1       cvs      1962: {
                   1963:   PresentationValue   margin;
                   1964:   
1.82      cvs      1965:   cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      1966:   /* first parse the attribute string */
                   1967:   cssRule = ParseCSSUnit (cssRule, &margin);
1.43      cvs      1968:   if (margin.typed_data.unit != STYLE_UNIT_INVALID)
                   1969:       TtaSetStylePresentation (PRMarginRight, element, tsch, context, margin);
1.1       cvs      1970:   return (cssRule);
                   1971: }
                   1972: 
                   1973: /*----------------------------------------------------------------------
1.59      cvs      1974:   ParseCSSMargin: parse a CSS margin attribute string
1.1       cvs      1975:   ----------------------------------------------------------------------*/
1.79      cvs      1976: static char *ParseCSSMargin (Element element, PSchema tsch,
1.78      cvs      1977:                               PresentationContext context,
1.79      cvs      1978:                               char *cssRule, CSSInfoPtr css,
1.78      cvs      1979:                               ThotBool isHTML)
1.1       cvs      1980: {
1.79      cvs      1981:   char *ptrT, *ptrR, *ptrB, *ptrL;
1.93      vatton   1982:   int   skippedNL;
1.1       cvs      1983: 
1.82      cvs      1984:   ptrT = SkipBlanksAndComments (cssRule);
1.1       cvs      1985:   /* First parse Margin-Top */
                   1986:   ptrR = ParseCSSMarginTop (element, tsch, context, ptrT, css, isHTML);
1.82      cvs      1987:   ptrR = SkipBlanksAndComments (ptrR);
                   1988:   if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.1       cvs      1989:     {
1.93      vatton   1990:       skippedNL = NewLineSkipped;
1.1       cvs      1991:       cssRule = ptrR;
                   1992:       /* apply the Margin-Top to all */
                   1993:       ptrR = ParseCSSMarginRight (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   1994:       NewLineSkipped = skippedNL;
1.1       cvs      1995:       ptrR = ParseCSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   1996:       NewLineSkipped = skippedNL;
1.1       cvs      1997:       ptrR = ParseCSSMarginLeft (element, tsch, context, ptrT, css, isHTML);
                   1998:     }
                   1999:   else
                   2000:     {
                   2001:       /* parse Margin-Right */
                   2002:       ptrB = ParseCSSMarginRight (element, tsch, context, ptrR, css, isHTML);
1.82      cvs      2003:       ptrB = SkipBlanksAndComments (ptrB);
                   2004:       if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.1       cvs      2005:        {
1.93      vatton   2006:          skippedNL = NewLineSkipped;
1.1       cvs      2007:          cssRule = ptrB;
                   2008:          /* apply the Margin-Top to Margin-Bottom */
                   2009:          ptrB = ParseCSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   2010:          NewLineSkipped = skippedNL;
1.1       cvs      2011:          /* apply the Margin-Right to Margin-Left */
                   2012:          ptrB = ParseCSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
                   2013:        }
                   2014:       else
                   2015:        {
                   2016:          /* parse Margin-Bottom */
                   2017:          ptrL = ParseCSSMarginBottom (element, tsch, context, ptrB, css, isHTML);
1.82      cvs      2018:          ptrL = SkipBlanksAndComments (ptrL);
                   2019:          if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.1       cvs      2020:            {
                   2021:              cssRule = ptrL;
                   2022:              /* apply the Margin-Right to Margin-Left */
                   2023:              ptrL = ParseCSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
                   2024:            }
                   2025:          else
                   2026:            /* parse Margin-Left */
                   2027:            cssRule = ParseCSSMarginLeft (element, tsch, context, ptrL, css, isHTML);
1.82      cvs      2028:          cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      2029:        }
                   2030:     }
                   2031:   return (cssRule);
                   2032: }
                   2033: 
                   2034: /*----------------------------------------------------------------------
1.59      cvs      2035:    ParseCSSPaddingTop: parse a CSS PaddingTop attribute string
1.1       cvs      2036:   ----------------------------------------------------------------------*/
1.79      cvs      2037: static char *ParseCSSPaddingTop (Element element, PSchema tsch,
1.78      cvs      2038:                                 PresentationContext context,
1.79      cvs      2039:                                   char *cssRule, CSSInfoPtr css,
1.78      cvs      2040:                                   ThotBool isHTML)
1.1       cvs      2041: {
1.43      cvs      2042:   PresentationValue   padding;
                   2043:   
1.82      cvs      2044:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      2045:   /* first parse the attribute string */
                   2046:   cssRule = ParseCSSUnit (cssRule, &padding);
                   2047:   if (padding.typed_data.unit != STYLE_UNIT_INVALID)
                   2048:       TtaSetStylePresentation (PRPaddingTop, element, tsch, context, padding);
1.1       cvs      2049:   return (cssRule);
                   2050: }
                   2051: 
                   2052: /*----------------------------------------------------------------------
1.59      cvs      2053:   ParseCSSPaddingBottom: parse a CSS PaddingBottom attribute string
1.1       cvs      2054:   ----------------------------------------------------------------------*/
1.79      cvs      2055: static char *ParseCSSPaddingBottom (Element element, PSchema tsch,
1.78      cvs      2056:                                      PresentationContext context,
1.79      cvs      2057:                                      char *cssRule, CSSInfoPtr css,
1.78      cvs      2058:                                      ThotBool isHTML)
1.1       cvs      2059: {
1.43      cvs      2060:   PresentationValue   padding;
                   2061:   
1.82      cvs      2062:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      2063:   /* first parse the attribute string */
                   2064:   cssRule = ParseCSSUnit (cssRule, &padding);
                   2065:   if (padding.typed_data.unit != STYLE_UNIT_INVALID)
                   2066:       TtaSetStylePresentation (PRPaddingBottom, element, tsch, context, padding);
1.1       cvs      2067:   return (cssRule);
                   2068: }
                   2069: 
                   2070: /*----------------------------------------------------------------------
1.59      cvs      2071:   ParseCSSPaddingLeft: parse a CSS PaddingLeft attribute string.
1.1       cvs      2072:   ----------------------------------------------------------------------*/
1.79      cvs      2073: static char *ParseCSSPaddingLeft (Element element, PSchema tsch,
1.78      cvs      2074:                                    PresentationContext context,
1.79      cvs      2075:                                    char *cssRule, CSSInfoPtr css,
1.78      cvs      2076:                                    ThotBool isHTML)
1.1       cvs      2077: {
1.43      cvs      2078:   PresentationValue   padding;
                   2079:   
1.82      cvs      2080:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      2081:   /* first parse the attribute string */
                   2082:   cssRule = ParseCSSUnit (cssRule, &padding);
                   2083:   if (padding.typed_data.unit != STYLE_UNIT_INVALID)
                   2084:       TtaSetStylePresentation (PRPaddingLeft, element, tsch, context, padding);
1.1       cvs      2085:   return (cssRule);
                   2086: }
                   2087: 
                   2088: /*----------------------------------------------------------------------
1.59      cvs      2089:   ParseCSSPaddingRight: parse a CSS PaddingRight attribute string.
1.1       cvs      2090:   ----------------------------------------------------------------------*/
1.79      cvs      2091: static char *ParseCSSPaddingRight (Element element, PSchema tsch,
1.78      cvs      2092:                                     PresentationContext context,
1.79      cvs      2093:                                     char *cssRule, CSSInfoPtr css,
1.78      cvs      2094:                                     ThotBool isHTML)
1.1       cvs      2095: {
1.43      cvs      2096:   PresentationValue   padding;
                   2097:   
1.82      cvs      2098:   cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      2099:   /* first parse the attribute string */
                   2100:   cssRule = ParseCSSUnit (cssRule, &padding);
                   2101:   if (padding.typed_data.unit != STYLE_UNIT_INVALID)
                   2102:       TtaSetStylePresentation (PRPaddingRight, element, tsch, context, padding);
1.1       cvs      2103:   return (cssRule);
                   2104: }
                   2105: 
                   2106: /*----------------------------------------------------------------------
1.59      cvs      2107:    ParseCSSPadding: parse a CSS padding attribute string. 
1.1       cvs      2108:   ----------------------------------------------------------------------*/
1.79      cvs      2109: static char *ParseCSSPadding (Element element, PSchema tsch,
1.78      cvs      2110:                                PresentationContext context,
1.79      cvs      2111:                                char *cssRule, CSSInfoPtr css,
1.78      cvs      2112:                                ThotBool isHTML)
1.1       cvs      2113: {
1.79      cvs      2114:   char *ptrT, *ptrR, *ptrB, *ptrL;
1.93      vatton   2115:   int   skippedNL;
1.43      cvs      2116: 
1.82      cvs      2117:   ptrT = SkipBlanksAndComments (cssRule);
1.43      cvs      2118:   /* First parse Padding-Top */
                   2119:   ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
1.82      cvs      2120:   ptrR = SkipBlanksAndComments (ptrR);
                   2121:   if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.43      cvs      2122:     {
1.93      vatton   2123:       skippedNL = NewLineSkipped;
1.43      cvs      2124:       cssRule = ptrR;
                   2125:       /* apply the Padding-Top to all */
                   2126:       ptrR = ParseCSSPaddingRight (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   2127:       NewLineSkipped = skippedNL;
1.43      cvs      2128:       ptrR = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   2129:       NewLineSkipped = skippedNL;
1.43      cvs      2130:       ptrR = ParseCSSPaddingLeft (element, tsch, context, ptrT, css, isHTML);
                   2131:     }
                   2132:   else
                   2133:     {
                   2134:       /* parse Padding-Right */
                   2135:       ptrB = ParseCSSPaddingRight (element, tsch, context, ptrR, css, isHTML);
1.82      cvs      2136:       ptrB = SkipBlanksAndComments (ptrB);
                   2137:       if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.43      cvs      2138:        {
1.93      vatton   2139:          skippedNL = NewLineSkipped;
1.43      cvs      2140:          cssRule = ptrB;
                   2141:          /* apply the Padding-Top to Padding-Bottom */
                   2142:          ptrB = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1.93      vatton   2143:          NewLineSkipped = skippedNL;
1.43      cvs      2144:          /* apply the Padding-Right to Padding-Left */
                   2145:          ptrB = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
                   2146:        }
                   2147:       else
                   2148:        {
                   2149:          /* parse Padding-Bottom */
                   2150:          ptrL = ParseCSSPaddingBottom (element, tsch, context, ptrB, css, isHTML);
1.82      cvs      2151:          ptrL = SkipBlanksAndComments (ptrL);
                   2152:          if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.43      cvs      2153:            {
                   2154:              cssRule = ptrL;
                   2155:              /* apply the Padding-Right to Padding-Left */
                   2156:              ptrL = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
                   2157:            }
                   2158:          else
                   2159:            /* parse Padding-Left */
                   2160:            cssRule = ParseCSSPaddingLeft (element, tsch, context, ptrL, css, isHTML);
1.82      cvs      2161:          cssRule = SkipBlanksAndComments (cssRule);
1.43      cvs      2162:        }
                   2163:     }
1.1       cvs      2164:   return (cssRule);
                   2165: }
                   2166: 
                   2167: /*----------------------------------------------------------------------
1.59      cvs      2168:    ParseCSSForeground: parse a CSS foreground attribute 
1.1       cvs      2169:   ----------------------------------------------------------------------*/
1.79      cvs      2170: static char *ParseCSSForeground (Element element, PSchema tsch,
1.78      cvs      2171:                                          PresentationContext context,
1.79      cvs      2172:                                          char *cssRule,
1.78      cvs      2173:                                          CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      2174: {
                   2175:    PresentationValue   best;
                   2176: 
                   2177:    cssRule = ParseCSSColor (cssRule, &best);
1.25      cvs      2178:    if (best.typed_data.unit != STYLE_UNIT_INVALID)
                   2179:      /* install the new presentation */
                   2180:      TtaSetStylePresentation (PRForeground, element, tsch, context, best);
1.1       cvs      2181:    return (cssRule);
                   2182: }
                   2183: 
                   2184: /*----------------------------------------------------------------------
1.59      cvs      2185:   ParseCSSBackgroundColor: parse a CSS background color attribute 
1.1       cvs      2186:   ----------------------------------------------------------------------*/
1.79      cvs      2187: static char *ParseCSSBackgroundColor (Element element, PSchema tsch,
1.78      cvs      2188:                                        PresentationContext context,
1.79      cvs      2189:                                        char *cssRule,
1.78      cvs      2190:                                        CSSInfoPtr css, ThotBool isHTML)
1.1       cvs      2191: {
                   2192:   PresentationValue     best;
                   2193:   unsigned int          savedtype = 0;
1.14      cvs      2194:   ThotBool              moved;
1.1       cvs      2195: 
                   2196:   /* move the BODY rule to the HTML element */
                   2197:   moved = (context->type == HTML_EL_BODY && isHTML);
                   2198:   if (moved)
                   2199:     {
                   2200:       if (element)
                   2201:        element = TtaGetMainRoot (context->doc);
                   2202:       else
                   2203:        {
                   2204:          savedtype = context->type;
1.83      cvs      2205:          context->type = HTML_EL_Document;
1.1       cvs      2206:        }
                   2207:     }
                   2208: 
                   2209:   best.typed_data.unit = STYLE_UNIT_INVALID;
                   2210:   best.typed_data.real = FALSE;
1.82      cvs      2211:   if (!strncasecmp (cssRule, "transparent", strlen ("transparent")))
1.1       cvs      2212:     {
                   2213:       best.typed_data.value = STYLE_PATTERN_NONE;
                   2214:       best.typed_data.unit = STYLE_UNIT_REL;
                   2215:       TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.65      cvs      2216:       cssRule = SkipWord (cssRule);
1.1       cvs      2217:     }
                   2218:   else
                   2219:     {
                   2220:       cssRule = ParseCSSColor (cssRule, &best);
                   2221:       if (best.typed_data.unit != STYLE_UNIT_INVALID)
                   2222:        {
                   2223:          /* install the new presentation. */
                   2224:          TtaSetStylePresentation (PRBackground, element, tsch, context, best);
1.59      cvs      2225:          /* thot specificity: need to set fill pattern for background color */
1.1       cvs      2226:          best.typed_data.value = STYLE_PATTERN_BACKGROUND;
                   2227:          best.typed_data.unit = STYLE_UNIT_REL;
                   2228:          TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
                   2229:          best.typed_data.value = 1;
                   2230:          best.typed_data.unit = STYLE_UNIT_REL;
                   2231:          TtaSetStylePresentation (PRShowBox, element, tsch, context, best);
                   2232:        }
                   2233:     }
                   2234: 
                   2235:   /* restore the refered element */
                   2236:   if (moved && !element)
                   2237:     context->type = savedtype;
                   2238:   return (cssRule);
                   2239: }
                   2240: 
1.63      cvs      2241: 
                   2242: /*----------------------------------------------------------------------
1.65      cvs      2243:   ParseSVGStroke: parse a SVG stroke property
                   2244:   ----------------------------------------------------------------------*/
1.79      cvs      2245: static char *ParseSVGStroke (Element element, PSchema tsch,
                   2246:                             PresentationContext context, char *cssRule,
                   2247:                             CSSInfoPtr css, ThotBool isHTML)
1.65      cvs      2248: {
                   2249:   PresentationValue     best;
                   2250: 
                   2251:   best.typed_data.unit = STYLE_UNIT_INVALID;
                   2252:   best.typed_data.real = FALSE;
1.82      cvs      2253:   if (!strncasecmp (cssRule, "none", 4))
1.65      cvs      2254:     {
                   2255:       best.typed_data.value = -2;  /* -2 means transparent */
                   2256:       best.typed_data.unit = STYLE_UNIT_REL;
                   2257:       TtaSetStylePresentation (PRForeground, element, tsch, context, best);
                   2258:       cssRule = SkipWord (cssRule);
                   2259:     }
                   2260:   else
                   2261:     {
                   2262:       cssRule = ParseCSSColor (cssRule, &best);
                   2263:       if (best.typed_data.unit != STYLE_UNIT_INVALID)
                   2264:        /* install the new presentation */
                   2265:        TtaSetStylePresentation (PRForeground, element, tsch, context, best);
                   2266:     }
                   2267:   return (cssRule);
                   2268: }
                   2269: 
                   2270: /*----------------------------------------------------------------------
1.63      cvs      2271:   ParseSVGFill: parse a SVG fill property
                   2272:   ----------------------------------------------------------------------*/
1.79      cvs      2273: static char *ParseSVGFill (Element element, PSchema tsch,
                   2274:                           PresentationContext context, char *cssRule,
                   2275:                           CSSInfoPtr css, ThotBool isHTML)
1.63      cvs      2276: {
                   2277:   PresentationValue     best;
                   2278: 
                   2279:   best.typed_data.unit = STYLE_UNIT_INVALID;
                   2280:   best.typed_data.real = FALSE;
1.82      cvs      2281:   if (!strncasecmp (cssRule, "none", 4))
1.63      cvs      2282:     {
                   2283:       best.typed_data.value = STYLE_PATTERN_NONE;
                   2284:       best.typed_data.unit = STYLE_UNIT_REL;
                   2285:       TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.65      cvs      2286:       cssRule = SkipWord (cssRule);
1.63      cvs      2287:     }
                   2288:   else
                   2289:     {
                   2290:       cssRule = ParseCSSColor (cssRule, &best);
                   2291:       if (best.typed_data.unit != STYLE_UNIT_INVALID)
                   2292:        {
                   2293:          /* install the new presentation. */
                   2294:          TtaSetStylePresentation (PRBackground, element, tsch, context, best);
                   2295:          /* thot specificity: need to set fill pattern for background color */
                   2296:          best.typed_data.value = STYLE_PATTERN_BACKGROUND;
                   2297:          best.typed_data.unit = STYLE_UNIT_REL;
                   2298:          TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
                   2299:        }
                   2300:     }
                   2301:   return (cssRule);
                   2302: }
                   2303: 
1.1       cvs      2304: /*----------------------------------------------------------------------
1.59      cvs      2305:   ParseCSSBackgroundImageCallback: Callback called asynchronously by
                   2306:   FetchImage when a background image has been fetched.
1.1       cvs      2307:   ----------------------------------------------------------------------*/
1.82      cvs      2308: void ParseCSSBackgroundImageCallback (Document doc, Element element,
                   2309:                                      char *file, void *extra)
1.1       cvs      2310: {
1.82      cvs      2311:   DisplayMode                dispMode;
                   2312:   BackgroundImageCallbackPtr callblock;
                   2313:   Element                    el;
                   2314:   PSchema                    tsch;
                   2315:   PresentationContext        context;
                   2316:   PresentationValue          image;
                   2317:   PresentationValue          value;
1.1       cvs      2318: 
1.82      cvs      2319:   callblock = (BackgroundImageCallbackPtr) extra;
1.34      cvs      2320:   if (callblock == NULL)
                   2321:     return;
1.1       cvs      2322: 
1.34      cvs      2323:   /* avoid too many redisplay */
                   2324:   dispMode = TtaGetDisplayMode (doc);
                   2325:   if (dispMode == DisplayImmediately)
                   2326:     TtaSetDisplayMode (doc, DeferredDisplay);
                   2327: 
                   2328:   el = callblock->el;
                   2329:   tsch = callblock->tsch;
                   2330:   context = &callblock->context.specific;
                   2331: 
                   2332:   /* Ok the image was fetched, finish the background-image handling */
                   2333:   image.pointer = file;
                   2334:   TtaSetStylePresentation (PRBackgroundPicture, el, tsch, context, image);
1.1       cvs      2335: 
1.70      cvs      2336:   /* enforce the showbox */
1.34      cvs      2337:   value.typed_data.value = 1;
                   2338:   value.typed_data.unit = STYLE_UNIT_REL;
                   2339:   value.typed_data.real = FALSE;
                   2340:   TtaSetStylePresentation (PRShowBox, el, tsch, context, value);
                   2341: 
                   2342:   TtaFreeMemory (callblock);
                   2343:   /* restore the display mode */
                   2344:   if (dispMode == DisplayImmediately)
                   2345:     TtaSetDisplayMode (doc, dispMode);
1.1       cvs      2346: }
                   2347: 
                   2348: 
                   2349: /*----------------------------------------------------------------------
                   2350:    GetCSSBackgroundURL searches a CSS BackgroundImage url within
                   2351:    the styleString.
                   2352:    Returns NULL or a new allocated url string.
                   2353:   ----------------------------------------------------------------------*/
1.79      cvs      2354: char *GetCSSBackgroundURL (char *styleString)
1.1       cvs      2355: {
1.79      cvs      2356:   char            *b, *e, *ptr;
                   2357:   int              len;
1.1       cvs      2358: 
                   2359:   ptr = NULL;
1.82      cvs      2360:   b = strstr (styleString, "url");
1.1       cvs      2361:   if (b != NULL)
                   2362:     {
                   2363:       b += 3;
1.82      cvs      2364:       b = SkipBlanksAndComments (b);
                   2365:       if (*b == '(')
1.1       cvs      2366:        {
                   2367:          b++;
1.82      cvs      2368:          b = SkipBlanksAndComments (b);
1.1       cvs      2369:          /*** Caution: Strings can either be written with double quotes or
                   2370:               with single quotes. Only double quotes are handled here.
                   2371:               Escaped quotes are not handled. See function SkipQuotedString */
1.82      cvs      2372:          if (*b == '"')
1.1       cvs      2373:            {
                   2374:              b++;
                   2375:              /* search the url end */
                   2376:              e = b;
1.82      cvs      2377:              while (*e != EOS && *e != '"')
1.1       cvs      2378:                e++;
                   2379:            }
                   2380:          else
                   2381:            {
                   2382:              /* search the url end */
                   2383:              e = b;
1.82      cvs      2384:              while (*e != EOS && *e != ')')
1.1       cvs      2385:                e++;
                   2386:            }
1.82      cvs      2387:          if (*e != EOS)
1.1       cvs      2388:            {
                   2389:              len = (int)(e - b);
1.82      cvs      2390:              ptr = (char*) TtaGetMemory (len+1);
                   2391:              strncpy (ptr, b, len);
                   2392:              ptr[len] = EOS;
1.1       cvs      2393:            }
                   2394:        }
                   2395:     }
                   2396:   return (ptr);
                   2397: }
                   2398: 
                   2399: 
                   2400: /*----------------------------------------------------------------------
1.59      cvs      2401:   ParseCSSBackgroundImage: parse a CSS BackgroundImage attribute string.
1.1       cvs      2402:   ----------------------------------------------------------------------*/
1.79      cvs      2403: static char *ParseCSSBackgroundImage (Element element, PSchema tsch,
                   2404:                                      PresentationContext context,
                   2405:                                      char *cssRule, CSSInfoPtr css,
                   2406:                                      ThotBool isHTML)
1.1       cvs      2407: {
1.49      cvs      2408:   Element                    el;
                   2409:   GenericContext             gblock;
1.71      cvs      2410:   PresentationContext        sblock;
1.1       cvs      2411:   BackgroundImageCallbackPtr callblock;
1.49      cvs      2412:   PresentationValue          image, value;
1.79      cvs      2413:   char                      *url;
1.82      cvs      2414:   char                      *bg_image;
1.79      cvs      2415:   char                       saved;
                   2416:   char                      *base;
                   2417:   char                       tempname[MAX_LENGTH];
                   2418:   char                       imgname[MAX_LENGTH];
1.49      cvs      2419:   unsigned int               savedtype = 0;
                   2420:   ThotBool                   moved;
1.1       cvs      2421: 
                   2422:   /* default element for FetchImage */
                   2423:   el = TtaGetMainRoot (context->doc);
                   2424:   /* move the BODY rule to the HTML element */
                   2425:   moved = (context->type == HTML_EL_BODY && isHTML);
                   2426:   if (moved)
                   2427:     {
                   2428:       if (element)
                   2429:        element = el;
                   2430:       else
                   2431:        {
                   2432:          savedtype = context->type;
1.83      cvs      2433:          context->type = HTML_EL_Document;
1.1       cvs      2434:        }
                   2435:     }
                   2436:   else if (element)
                   2437:     el = element;
                   2438: 
                   2439:   url = NULL;
1.82      cvs      2440:   cssRule = SkipBlanksAndComments (cssRule);
                   2441:   if (!strncasecmp (cssRule, "url", 3))
1.1       cvs      2442:     {  
                   2443:       cssRule += 3;
1.82      cvs      2444:       cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      2445:       if (*cssRule == '(')
                   2446:        {
                   2447:          cssRule++;
1.82      cvs      2448:          cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      2449:          /*** Caution: Strings can either be written with double quotes or
                   2450:            with single quotes. Only double quotes are handled here.
                   2451:            Escaped quotes are not handled. See function SkipQuotedString */
                   2452:          if (*cssRule == '"')
                   2453:            {
                   2454:              cssRule++;
                   2455:              base = cssRule;
1.82      cvs      2456:              while (*cssRule != EOS && *cssRule != '"')
1.1       cvs      2457:                cssRule++;
                   2458:            }
                   2459:          else
                   2460:            {
                   2461:              base = cssRule;
                   2462:              while (*cssRule != EOS && *cssRule != ')')
                   2463:                cssRule++;
                   2464:            }
                   2465:          saved = *cssRule;
1.82      cvs      2466:          *cssRule = EOS;
                   2467:          url = TtaStrdup (base);
1.1       cvs      2468:          *cssRule = saved;
                   2469:          if (saved == '"')
                   2470:            /* we need to skip two characters */
                   2471:            cssRule++;      
                   2472:        }
                   2473:       cssRule++;
                   2474: 
                   2475:       if (context->destroy)
                   2476:        {
                   2477:          /* remove the background image PRule */
                   2478:          image.pointer = NULL;
                   2479:          TtaSetStylePresentation (PRBackgroundPicture, element, tsch, context, image);
                   2480:          if (TtaGetStylePresentation (PRFillPattern, element, tsch, context, &value) < 0)
                   2481:            {
                   2482:              /* there is no FillPattern rule -> remove ShowBox rule */
                   2483:              value.typed_data.value = 1;
                   2484:              value.typed_data.unit = STYLE_UNIT_REL;
                   2485:              value.typed_data.real = FALSE;
                   2486:              TtaSetStylePresentation (PRShowBox, element, tsch, context, value);
                   2487:            }
                   2488:        }
                   2489:       else if (url)
                   2490:        {
1.30      cvs      2491:          bg_image = TtaGetEnvString ("ENABLE_BG_IMAGES");
1.82      cvs      2492:          if (bg_image == NULL || !strcasecmp (bg_image, "yes"))
1.1       cvs      2493:            {
                   2494:              callblock = (BackgroundImageCallbackPtr) TtaGetMemory(sizeof(BackgroundImageCallbackBlock));
                   2495:              if (callblock != NULL)
                   2496:                {
                   2497:                  callblock->el = element;
                   2498:                  callblock->tsch = tsch;
                   2499:                  if (element == NULL)
1.18      cvs      2500:                    {
                   2501:                      gblock = (GenericContext) context;
                   2502:                      memcpy (&callblock->context.generic, gblock,
                   2503:                              sizeof (GenericContextBlock));
                   2504:                    }
                   2505:                  else
                   2506:                    {
                   2507:                      sblock = context;
                   2508:                      memcpy (&callblock->context.specific, sblock,
                   2509:                              sizeof(PresentationContextBlock));
                   2510:                    }
                   2511: 
                   2512:                  /* check if the image url is related to an external CSS */
                   2513:                  if (css != NULL && css->category == CSS_EXTERNAL_STYLE)
                   2514:                    {
                   2515:                      NormalizeURL (url, 0, tempname, imgname, css->url);
                   2516:                      /* fetch and display background image of element */
1.49      cvs      2517:                      FetchImage (context->doc, el, tempname, AMAYA_LOAD_IMAGE, ParseCSSBackgroundImageCallback, callblock);
1.18      cvs      2518:                    }
                   2519:                  else
1.49      cvs      2520:                    FetchImage (context->doc, el, url, AMAYA_LOAD_IMAGE, ParseCSSBackgroundImageCallback, callblock);
1.18      cvs      2521:                }
                   2522:            }
                   2523: 
                   2524:          if (url)
                   2525:            TtaFreeMemory (url);
                   2526:        }
                   2527:     }
                   2528: 
                   2529:   /* restore the refered element */
                   2530:   if (moved && !element)
                   2531:     context->type = savedtype;
                   2532:   return (cssRule);
                   2533: }
                   2534: 
                   2535: /*----------------------------------------------------------------------
1.59      cvs      2536:   ParseCSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
1.18      cvs      2537:   ----------------------------------------------------------------------*/
1.79      cvs      2538: static char *ParseCSSBackgroundRepeat (Element element, PSchema tsch,
                   2539:                                 PresentationContext context, char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18      cvs      2540: {
                   2541:   PresentationValue   repeat;
                   2542:   unsigned int        savedtype = 0;
                   2543:   ThotBool            moved;
                   2544: 
                   2545:   /* move the BODY rule to the HTML element */
                   2546:   moved = (context->type == HTML_EL_BODY && isHTML);
                   2547:   if (moved)
                   2548:     {
                   2549:       if (element)
                   2550:        element = TtaGetMainRoot (context->doc);
                   2551:       else
                   2552:        {
                   2553:          savedtype = context->type;
1.83      cvs      2554:          context->type = HTML_EL_Document;
1.18      cvs      2555:        }
                   2556:     }
                   2557: 
                   2558:   repeat.typed_data.value = STYLE_REALSIZE;
                   2559:   repeat.typed_data.unit = STYLE_UNIT_REL;
                   2560:   repeat.typed_data.real = FALSE;
1.82      cvs      2561:   cssRule = SkipBlanksAndComments (cssRule);
                   2562:   if (!strncasecmp (cssRule, "no-repeat", 9))
1.18      cvs      2563:     repeat.typed_data.value = STYLE_REALSIZE;
1.82      cvs      2564:   else if (!strncasecmp (cssRule, "repeat-y", 8))
1.18      cvs      2565:     repeat.typed_data.value = STYLE_VREPEAT;
1.82      cvs      2566:   else if (!strncasecmp (cssRule, "repeat-x", 8))
1.18      cvs      2567:     repeat.typed_data.value = STYLE_HREPEAT;
1.82      cvs      2568:   else if (!strncasecmp (cssRule, "repeat", 6))
1.18      cvs      2569:     repeat.typed_data.value = STYLE_REPEAT;
                   2570:   else
                   2571:     return (cssRule);
                   2572: 
                   2573:    /* install the new presentation */
                   2574:   TtaSetStylePresentation (PRPictureMode, element, tsch, context, repeat);
                   2575:   cssRule = SkipWord (cssRule);
                   2576: 
                   2577:   /* restore the refered element */
                   2578:   if (moved && !element)
                   2579:     context->type = savedtype;
                   2580:    return (cssRule);
                   2581: }
                   2582: 
                   2583: /*----------------------------------------------------------------------
1.59      cvs      2584:    ParseCSSBackgroundAttachment: parse a CSS BackgroundAttachment
1.18      cvs      2585:    attribute string.                                          
                   2586:   ----------------------------------------------------------------------*/
1.79      cvs      2587: static char *ParseCSSBackgroundAttachment (Element element, PSchema tsch,
                   2588:                                           PresentationContext context,
                   2589:                                           char *cssRule, CSSInfoPtr css,
                   2590:                                           ThotBool isHTML)
1.18      cvs      2591: {
                   2592:   unsigned int          savedtype = 0;
                   2593:   ThotBool              moved;
1.1       cvs      2594: 
1.18      cvs      2595:   /* move the BODY rule to the HTML element */
                   2596:   moved = (context->type == HTML_EL_BODY && isHTML);
                   2597:   if (moved)
                   2598:     {
                   2599:       if (element)
                   2600:        element = TtaGetMainRoot (context->doc);
                   2601:       else
                   2602:        {
                   2603:          savedtype = context->type;
1.83      cvs      2604:          context->type = HTML_EL_Document;
1.1       cvs      2605:        }
                   2606:     }
                   2607: 
1.82      cvs      2608:    cssRule = SkipBlanksAndComments (cssRule);
                   2609:    if (!strncasecmp (cssRule, "scroll", 6))
1.18      cvs      2610:      cssRule = SkipWord (cssRule);
1.82      cvs      2611:    else if (!strncasecmp (cssRule, "fixed", 5))
1.18      cvs      2612:      cssRule = SkipWord (cssRule);
                   2613: 
1.1       cvs      2614:   /* restore the refered element */
                   2615:   if (moved && !element)
                   2616:     context->type = savedtype;
1.18      cvs      2617:    return (cssRule);
1.1       cvs      2618: }
                   2619: 
                   2620: /*----------------------------------------------------------------------
1.59      cvs      2621:    ParseCSSBackgroundPosition: parse a CSS BackgroundPosition
1.1       cvs      2622:    attribute string.                                          
                   2623:   ----------------------------------------------------------------------*/
1.79      cvs      2624: static char *ParseCSSBackgroundPosition (Element element, PSchema tsch,
                   2625:                                         PresentationContext context,
                   2626:                                         char *cssRule, CSSInfoPtr css,
                   2627:                                         ThotBool isHTML)
1.1       cvs      2628: {
1.18      cvs      2629:   PresentationValue     repeat;
                   2630:   unsigned int          savedtype = 0;
                   2631:   ThotBool              moved;
                   2632:   ThotBool              ok;
1.1       cvs      2633: 
                   2634:   /* move the BODY rule to the HTML element */
                   2635:   moved = (context->type == HTML_EL_BODY && isHTML);
                   2636:   if (moved)
                   2637:     {
                   2638:       if (element)
                   2639:        element = TtaGetMainRoot (context->doc);
                   2640:       else
                   2641:        {
                   2642:          savedtype = context->type;
1.83      cvs      2643:          context->type = HTML_EL_Document;
1.1       cvs      2644:        }
                   2645:     }
                   2646: 
1.82      cvs      2647:    cssRule = SkipBlanksAndComments (cssRule);
1.18      cvs      2648:    ok = TRUE;
1.82      cvs      2649:    if (!strncasecmp (cssRule, "left", 4))
1.18      cvs      2650:      cssRule = SkipWord (cssRule);
1.82      cvs      2651:    else if (!strncasecmp (cssRule, "right", 5))
1.18      cvs      2652:      cssRule = SkipWord (cssRule);
1.82      cvs      2653:    else if (!strncasecmp (cssRule, "center", 6))
1.18      cvs      2654:      cssRule = SkipWord (cssRule);
1.82      cvs      2655:    else if (!strncasecmp (cssRule, "top", 3))
1.18      cvs      2656:      cssRule = SkipWord (cssRule);
1.82      cvs      2657:    else if (!strncasecmp (cssRule, "bottom", 6))
1.18      cvs      2658:      cssRule = SkipWord (cssRule);
1.82      cvs      2659:    else if (isdigit (*cssRule))
1.18      cvs      2660:      cssRule = SkipWord (cssRule);
                   2661:    else
                   2662:      ok = FALSE;
                   2663: 
                   2664:    if (ok)
                   2665:      {
                   2666:        /* force realsize for the background image */
                   2667:        repeat.typed_data.value = STYLE_REALSIZE;
                   2668:        repeat.typed_data.unit = STYLE_UNIT_REL;
                   2669:        repeat.typed_data.real = FALSE;
                   2670:        TtaSetStylePresentation (PRPictureMode, element, tsch, context, repeat);
                   2671:      }
                   2672: 
                   2673:   /* restore the refered element */
                   2674:   if (moved && !element)
                   2675:     context->type = savedtype;
                   2676:    return (cssRule);
                   2677: }
                   2678: 
                   2679: /*----------------------------------------------------------------------
1.59      cvs      2680:    ParseCSSBackground: parse a CSS background attribute 
1.18      cvs      2681:   ----------------------------------------------------------------------*/
1.79      cvs      2682: static char *ParseCSSBackground (Element element, PSchema tsch,
                   2683:                                 PresentationContext context, char *cssRule,
                   2684:                                 CSSInfoPtr css, ThotBool isHTML)
1.18      cvs      2685: {
1.79      cvs      2686:   char     *ptr;
1.93      vatton   2687:   int   skippedNL;
1.18      cvs      2688: 
1.82      cvs      2689:   cssRule = SkipBlanksAndComments (cssRule);
                   2690:   while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.18      cvs      2691:     {
1.71      cvs      2692:       /* perhaps a Background Image */
1.82      cvs      2693:       if (!strncasecmp (cssRule, "url", 3))
1.63      cvs      2694:          cssRule = ParseCSSBackgroundImage (element, tsch, context, cssRule,
                   2695:                                            css, isHTML);
1.18      cvs      2696:       /* perhaps a Background Attachment */
1.82      cvs      2697:       else if (!strncasecmp (cssRule, "scroll", 6) ||
                   2698:                !strncasecmp (cssRule, "fixed", 5))
1.63      cvs      2699:        cssRule = ParseCSSBackgroundAttachment (element, tsch, context,
                   2700:                                                cssRule, css, isHTML);
1.18      cvs      2701:       /* perhaps a Background Repeat */
1.82      cvs      2702:       else if (!strncasecmp (cssRule, "no-repeat", 9) ||
                   2703:                !strncasecmp (cssRule, "repeat-y", 8)  ||
                   2704:                !strncasecmp (cssRule, "repeat-x", 8)  ||
                   2705:                !strncasecmp (cssRule, "repeat", 6))
                   2706:        cssRule = ParseCSSBackgroundRepeat (element, tsch, context,
                   2707:                                            cssRule, css, isHTML);
1.18      cvs      2708:       /* perhaps a Background Position */
1.82      cvs      2709:       else if (!strncasecmp (cssRule, "left", 4)   ||
                   2710:                !strncasecmp (cssRule, "right", 5)  ||
                   2711:                !strncasecmp (cssRule, "center", 6) ||
                   2712:                !strncasecmp (cssRule, "top", 3)    ||
                   2713:                !strncasecmp (cssRule, "bottom", 6) ||
                   2714:                isdigit (*cssRule))
1.63      cvs      2715:            cssRule = ParseCSSBackgroundPosition (element, tsch, context,
                   2716:                                                 cssRule, css, isHTML);
1.18      cvs      2717:       /* perhaps a Background Color */
                   2718:       else
                   2719:        {
1.93      vatton   2720:          skippedNL = NewLineSkipped;
1.18      cvs      2721:          /* check if the rule has been found */
                   2722:          ptr = cssRule;
1.82      cvs      2723:          cssRule = ParseCSSBackgroundColor (element, tsch, context,
                   2724:                                             cssRule, css, isHTML);
1.43      cvs      2725:          if (ptr == cssRule)
1.93      vatton   2726:            {
                   2727:              NewLineSkipped = skippedNL;
                   2728:              /* rule not found */
                   2729:              cssRule = SkipProperty (cssRule);
                   2730:            }
1.18      cvs      2731:        }
1.82      cvs      2732:       cssRule = SkipBlanksAndComments (cssRule);
1.18      cvs      2733:     }
                   2734:    return (cssRule);
                   2735: }
                   2736: 
1.59      cvs      2737: /*----------------------------------------------------------------------
1.60      cvs      2738:  ParseCSSPageBreakBefore: parse a CSS page-break-before attribute 
1.59      cvs      2739:   ----------------------------------------------------------------------*/
1.79      cvs      2740: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
                   2741:                                      PresentationContext context, char *cssRule,
                   2742:                                      CSSInfoPtr css, ThotBool isHTML)
1.59      cvs      2743: {
                   2744:   PresentationValue   page;
                   2745: 
                   2746:   page.typed_data.unit = STYLE_UNIT_INVALID;
                   2747:   page.typed_data.real = FALSE;
1.82      cvs      2748:   cssRule = SkipBlanksAndComments (cssRule);
                   2749:   if (!strncasecmp (cssRule, "auto", 4))
1.59      cvs      2750:     {
                   2751:       /*page.typed_data.unit = STYLE_UNIT_REL;*/
                   2752:       page.typed_data.value = STYLE_AUTO;
                   2753:     }
1.82      cvs      2754:   else if (!strncasecmp (cssRule, "always", 6))
1.59      cvs      2755:     {
                   2756:       page.typed_data.unit = STYLE_UNIT_REL;
                   2757:       page.typed_data.value = STYLE_ALWAYS;
                   2758:     }
1.82      cvs      2759:   else if (!strncasecmp (cssRule, "avoid", 5))
1.59      cvs      2760:     {
                   2761:       page.typed_data.unit = STYLE_UNIT_REL;
                   2762:       page.typed_data.value = STYLE_AVOID;
                   2763:     }
1.82      cvs      2764:   else if (!strncasecmp (cssRule, "left", 4))
1.59      cvs      2765:     {
                   2766:       page.typed_data.unit = STYLE_UNIT_REL;
                   2767:       page.typed_data.value = STYLE_PAGELEFT;
                   2768:     }
1.82      cvs      2769:   else if (!strncasecmp (cssRule, "right", 5))
1.59      cvs      2770:     {
                   2771:       page.typed_data.unit = STYLE_UNIT_REL;
                   2772:       page.typed_data.value = STYLE_PAGERIGHT;
                   2773:     }
1.82      cvs      2774:   else if (!strncasecmp (cssRule, "inherit", 7))
1.59      cvs      2775:     {
                   2776:       /*page.typed_data.unit = STYLE_UNIT_REL;*/
                   2777:       page.typed_data.value = STYLE_INHERIT;
                   2778:     }
                   2779:   cssRule = SkipWord (cssRule);
                   2780:   /* install the new presentation */
                   2781:   if (page.typed_data.unit == STYLE_UNIT_REL &&
                   2782:       page.typed_data.value == STYLE_ALWAYS)
                   2783:     TtaSetStylePresentation (PRPageBefore, element, tsch, context, page);
                   2784:   return (cssRule);
                   2785: }
                   2786: 
                   2787: /*----------------------------------------------------------------------
1.60      cvs      2788:  ParseCSSPageBreakAfter: parse a CSS page-break-after attribute 
1.59      cvs      2789:   ----------------------------------------------------------------------*/
1.79      cvs      2790: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
                   2791:                                     PresentationContext context,
                   2792:                                     char *cssRule, CSSInfoPtr css,
                   2793:                                     ThotBool isHTML)
1.59      cvs      2794: {
                   2795:   PresentationValue   page;
                   2796: 
                   2797:   page.typed_data.unit = STYLE_UNIT_INVALID;
                   2798:   page.typed_data.real = FALSE;
1.82      cvs      2799:   cssRule = SkipBlanksAndComments (cssRule);
                   2800:   if (!strncasecmp (cssRule, "auto", 4))
1.59      cvs      2801:     {
                   2802:       /*page.typed_data.unit = STYLE_UNIT_REL;*/
                   2803:       page.typed_data.value = STYLE_AUTO;
                   2804:     }
1.82      cvs      2805:   else if (!strncasecmp (cssRule, "always", 6))
1.59      cvs      2806:     {
                   2807:       page.typed_data.unit = STYLE_UNIT_REL;
                   2808:       page.typed_data.value = STYLE_ALWAYS;
                   2809:     }
1.82      cvs      2810:   else if (!strncasecmp (cssRule, "avoid", 5))
1.59      cvs      2811:     {
                   2812:       page.typed_data.unit = STYLE_UNIT_REL;
                   2813:       page.typed_data.value = STYLE_AVOID;
                   2814:     }
1.82      cvs      2815:   else if (!strncasecmp (cssRule, "left", 4))
1.59      cvs      2816:     {
                   2817:       page.typed_data.unit = STYLE_UNIT_REL;
                   2818:       page.typed_data.value = STYLE_PAGELEFT;
                   2819:     }
1.82      cvs      2820:   else if (!strncasecmp (cssRule, "right", 5))
1.59      cvs      2821:     {
                   2822:       page.typed_data.unit = STYLE_UNIT_REL;
                   2823:       page.typed_data.value = STYLE_PAGERIGHT;
                   2824:     }
1.82      cvs      2825:   else if (!strncasecmp (cssRule, "inherit", 7))
1.59      cvs      2826:     {
                   2827:       /*page.typed_data.unit = STYLE_UNIT_REL;*/
                   2828:       page.typed_data.value = STYLE_INHERIT;
                   2829:     }
                   2830:   cssRule = SkipWord (cssRule);
                   2831:   /* install the new presentation */
                   2832:   /*if (page.typed_data.unit == STYLE_UNIT_REL)
                   2833:     TtaSetStylePresentation (PRPageAfter, element, tsch, context, page);*/
                   2834:   return (cssRule);
                   2835: }
                   2836: 
                   2837: /*----------------------------------------------------------------------
1.60      cvs      2838:  ParseCSSPageBreakInside: parse a CSS page-break-inside attribute 
1.59      cvs      2839:   ----------------------------------------------------------------------*/
1.79      cvs      2840: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
                   2841:                                      PresentationContext context,
                   2842:                                      char *cssRule, CSSInfoPtr css,
                   2843:                                      ThotBool isHTML)
1.59      cvs      2844: {
                   2845:   PresentationValue   page;
                   2846: 
                   2847:   page.typed_data.unit = STYLE_UNIT_INVALID;
                   2848:   page.typed_data.real = FALSE;
1.82      cvs      2849:   cssRule = SkipBlanksAndComments (cssRule);
                   2850:   if (!strncasecmp (cssRule, "auto", 4))
1.59      cvs      2851:     {
                   2852:       /*page.typed_data.unit = STYLE_UNIT_REL;*/
                   2853:       page.typed_data.value = STYLE_AUTO;
                   2854:     }
1.82      cvs      2855:   else if (!strncasecmp (cssRule, "avoid", 5))
1.59      cvs      2856:     {
                   2857:       page.typed_data.unit = STYLE_UNIT_REL;
                   2858:       page.typed_data.value = STYLE_AVOID;
                   2859:     }
1.82      cvs      2860:   else if (!strncasecmp (cssRule, "inherit", 7))
1.59      cvs      2861:     {
                   2862:       /*page.typed_data.unit = STYLE_UNIT_REL;*/
                   2863:       page.typed_data.value = STYLE_INHERIT;
                   2864:     }
                   2865:   cssRule = SkipWord (cssRule);
                   2866:   /* install the new presentation */
                   2867:   if (page.typed_data.unit == STYLE_UNIT_REL &&
                   2868:       page.typed_data.value == STYLE_AVOID)
                   2869:     TtaSetStylePresentation (PRPageInside, element, tsch, context, page);
                   2870:   return (cssRule);
                   2871: }
1.18      cvs      2872: 
                   2873: 
1.60      cvs      2874: /*----------------------------------------------------------------------
1.63      cvs      2875:    ParseSVGStrokeWidth: parse a SVG stroke-width property value.                                          
1.60      cvs      2876:   ----------------------------------------------------------------------*/
1.79      cvs      2877: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
                   2878:                                  PresentationContext context, char *cssRule,
                   2879:                                  CSSInfoPtr css, ThotBool isHTML)
1.60      cvs      2880: {
                   2881:   PresentationValue   width;
                   2882:   
1.82      cvs      2883:   cssRule = SkipBlanksAndComments (cssRule);
1.60      cvs      2884:   width.typed_data.value = 0;
                   2885:   width.typed_data.unit = STYLE_UNIT_INVALID;
                   2886:   width.typed_data.real = FALSE;
1.82      cvs      2887:   if (isdigit (*cssRule))
1.60      cvs      2888:      cssRule = ParseCSSUnit (cssRule, &width);
                   2889:   if (width.typed_data.unit != STYLE_UNIT_INVALID)
                   2890:      {
                   2891:      TtaSetStylePresentation (PRLineWeight, element, tsch, context, width);
                   2892:      width.typed_data.value = 1;
                   2893:      width.typed_data.unit = STYLE_UNIT_REL;
                   2894:      }
                   2895:   return (cssRule);
                   2896: }
                   2897: 
1.18      cvs      2898: /************************************************************************
                   2899:  *                                                                     *  
                   2900:  *     FUNCTIONS STYLE DECLARATIONS                                    *
                   2901:  *                                                                     *  
                   2902:  ************************************************************************/
                   2903: /*
1.59      cvs      2904:  * NOTE: Long attribute name MUST be placed before shortened ones !
1.18      cvs      2905:  *        e.g. "FONT-SIZE" must be placed before "FONT"
                   2906:  */
                   2907: static CSSProperty CSSProperties[] =
                   2908: {
1.82      cvs      2909:    {"font-family", ParseCSSFontFamily},
                   2910:    {"font-style", ParseCSSFontStyle},
                   2911:    {"font-variant", ParseCSSFontVariant},
                   2912:    {"font-weight", ParseCSSFontWeight},
                   2913:    {"font-size", ParseCSSFontSize},
                   2914:    {"font", ParseCSSFont},
                   2915: 
                   2916:    {"color", ParseCSSForeground},
                   2917:    {"background-color", ParseCSSBackgroundColor},
                   2918:    {"background-image", ParseCSSBackgroundImage},
                   2919:    {"background-repeat", ParseCSSBackgroundRepeat},
                   2920:    {"background-attachment", ParseCSSBackgroundAttachment},
                   2921:    {"background-position", ParseCSSBackgroundPosition},
                   2922:    {"background", ParseCSSBackground},
                   2923: 
                   2924:    {"word-spacing", ParseCSSWordSpacing},
                   2925:    {"letter-spacing", ParseCSSLetterSpacing},
                   2926:    {"text-decoration", ParseCSSTextDecoration},
                   2927:    {"vertical-align", ParseCSSVerticalAlign},
                   2928:    {"text-transform", ParseCSSTextTransform},
                   2929:    {"text-align", ParseCSSTextAlign},
                   2930:    {"text-indent", ParseCSSTextIndent},
                   2931:    {"line-height", ParseCSSLineSpacing},
                   2932: 
                   2933:    {"margin-top", ParseCSSMarginTop},
                   2934:    {"margin-right", ParseCSSMarginRight},
                   2935:    {"margin-bottom", ParseCSSMarginBottom},
                   2936:    {"margin-left", ParseCSSMarginLeft},
                   2937:    {"margin", ParseCSSMargin},
                   2938: 
                   2939:    {"padding-top", ParseCSSPaddingTop},
                   2940:    {"padding-right", ParseCSSPaddingRight},
                   2941:    {"padding-bottom", ParseCSSPaddingBottom},
                   2942:    {"padding-left", ParseCSSPaddingLeft},
                   2943:    {"padding", ParseCSSPadding},
                   2944: 
                   2945:    {"border-top-width", ParseCSSBorderTopWidth},
                   2946:    {"border-right-width", ParseCSSBorderRightWidth},
                   2947:    {"border-bottom-width", ParseCSSBorderBottomWidth},
                   2948:    {"border-left-width", ParseCSSBorderLeftWidth},
                   2949:    {"border-width", ParseCSSBorderWidth},
                   2950:    {"border-top-color", ParseCSSBorderColorTop},
                   2951:    {"border-right-color", ParseCSSBorderColorRight},
                   2952:    {"border-bottom-color", ParseCSSBorderColorBottom},
                   2953:    {"border-left-color", ParseCSSBorderColorLeft},
                   2954:    {"border-color", ParseCSSBorderColor},
                   2955:    {"border-top-style", ParseCSSBorderStyleTop},
                   2956:    {"border-right-style", ParseCSSBorderStyleRight},
                   2957:    {"border-bottom-style", ParseCSSBorderStyleBottom},
                   2958:    {"border-left-style", ParseCSSBorderStyleLeft},
                   2959:    {"border-style", ParseCSSBorderStyle},
                   2960:    {"border-top", ParseCSSBorderTop},
                   2961:    {"border-right", ParseCSSBorderRight},
                   2962:    {"border-bottom", ParseCSSBorderBottom},
                   2963:    {"border-left", ParseCSSBorderLeft},
                   2964:    {"border", ParseCSSBorder},
                   2965: 
                   2966:    {"width", ParseCSSWidth},
                   2967:    {"height", ParseCSSHeight},
                   2968:    {"float", ParseCSSFloat},
                   2969:    {"clear", ParseCSSClear},
                   2970: 
                   2971:    {"display", ParseCSSDisplay},
                   2972:    {"white-space", ParseCSSWhiteSpace},
                   2973: 
                   2974:    {"list-style-type", ParseCSSListStyleType},
                   2975:    {"list-style-image", ParseCSSListStyleImage},
                   2976:    {"list-style-position", ParseCSSListStylePosition},
                   2977:    {"list-style", ParseCSSListStyle},
                   2978: 
                   2979:    {"page-break-before", ParseCSSPageBreakBefore},
                   2980:    {"page-break-after", ParseCSSPageBreakAfter},
                   2981:    {"page-break-inside", ParseCSSPageBreakInside},
1.60      cvs      2982: 
                   2983:    /* SVG extensions */
1.82      cvs      2984:    {"stroke-width", ParseSVGStrokeWidth},
                   2985:    {"stroke", ParseSVGStroke},
                   2986:    {"fill", ParseSVGFill}
1.18      cvs      2987: };
                   2988: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
                   2989: 
                   2990: /*----------------------------------------------------------------------
1.59      cvs      2991:    ParseCSSRule: parse a CSS Style string                        
1.18      cvs      2992:    we expect the input string describing the style to be of the  
1.59      cvs      2993:    form: PRORPERTY: DESCRIPTION [ ; PROPERTY: DESCRIPTION ] * 
1.18      cvs      2994:    but tolerate incorrect or incomplete input                    
                   2995:   ----------------------------------------------------------------------*/
1.79      cvs      2996: static void  ParseCSSRule (Element element, PSchema tsch,
                   2997:                           PresentationContext context, char *cssRule,
                   2998:                           CSSInfoPtr css, ThotBool isHTML)
1.18      cvs      2999: {
1.34      cvs      3000:   DisplayMode         dispMode;
1.79      cvs      3001:   char               *p = NULL;
1.18      cvs      3002:   int                 lg;
1.34      cvs      3003:   unsigned int        i;
1.76      cvs      3004:   ThotBool            found;
1.18      cvs      3005: 
1.34      cvs      3006:   /* avoid too many redisplay */
                   3007:   dispMode = TtaGetDisplayMode (context->doc);
                   3008:   if (dispMode == DisplayImmediately)
                   3009:     TtaSetDisplayMode (context->doc, DeferredDisplay);
                   3010: 
1.82      cvs      3011:   while (*cssRule != EOS)
1.18      cvs      3012:     {
1.82      cvs      3013:       cssRule = SkipBlanksAndComments (cssRule);
1.89      cvs      3014:       if (*cssRule == '{')
                   3015:        {
                   3016:          cssRule++;
                   3017:          CSSParseError ("Invalid character", "{");
                   3018:          cssRule = SkipBlanksAndComments (cssRule);
                   3019:        }
1.18      cvs      3020:       
                   3021:       found = FALSE;
                   3022:       /* look for the type of property */
                   3023:       for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
                   3024:        {
1.82      cvs      3025:          lg = strlen (CSSProperties[i].name);
                   3026:          if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
1.18      cvs      3027:            {
1.86      cvs      3028:              p = cssRule + lg;
1.18      cvs      3029:              found = TRUE;
                   3030:              i--;
                   3031:            }
                   3032:        }
                   3033: 
                   3034:       if (i == NB_CSSSTYLEATTRIBUTE)
                   3035:        cssRule = SkipProperty (cssRule);
                   3036:       else
                   3037:        {
                   3038:          /* update index and skip the ":" indicator if present */
1.86      cvs      3039:          p = SkipBlanksAndComments (p);
                   3040:          if (*p == ':')
1.18      cvs      3041:            {
1.86      cvs      3042:              p++;
                   3043:              p = SkipBlanksAndComments (p);
1.74      cvs      3044:              /* try to parse the value associated with this property */
                   3045:              if (CSSProperties[i].parsing_function != NULL)
1.61      cvs      3046:                {
1.75      cvs      3047:                  p = CSSProperties[i].parsing_function (element, tsch, context,
1.86      cvs      3048:                                                         p, css, isHTML);
1.74      cvs      3049:                  /* update index and skip the ";" separator if present */
                   3050:                  cssRule = p;
1.61      cvs      3051:                }
1.18      cvs      3052:            }
1.74      cvs      3053:          else
                   3054:            cssRule = SkipProperty (cssRule);
1.18      cvs      3055:        }
1.89      cvs      3056: 
1.18      cvs      3057:       /* next property */
1.82      cvs      3058:       cssRule = SkipBlanksAndComments (cssRule);
1.89      cvs      3059:       if (*cssRule == '}')
                   3060:        {
                   3061:          cssRule++;
                   3062:          CSSParseError ("Invalid character", "}");
                   3063:          cssRule = SkipBlanksAndComments (cssRule);
                   3064:        }
1.82      cvs      3065:       if (*cssRule == ',' || *cssRule == ';')
1.18      cvs      3066:        {
                   3067:          cssRule++;
1.82      cvs      3068:          cssRule = SkipBlanksAndComments (cssRule);
1.18      cvs      3069:        }
                   3070:     }
1.34      cvs      3071: 
                   3072:   /* restore the display mode */
                   3073:   if (dispMode == DisplayImmediately)
                   3074:     TtaSetDisplayMode (context->doc, dispMode);
1.18      cvs      3075: }
1.1       cvs      3076: 
                   3077: 
                   3078: /*----------------------------------------------------------------------
1.59      cvs      3079:  PToCss:  translate a PresentationSetting to the
1.18      cvs      3080:      equivalent CSS string, and add it to the buffer given as the
1.67      cvs      3081:      argument. It is used when extracting the CSS string from actual
                   3082:      presentation.
                   3083:      el is the element for which the style rule is generated
1.18      cvs      3084:  
                   3085:   All the possible values returned by the presentation drivers are
                   3086:   described in thotlib/include/presentation.h
                   3087:  -----------------------------------------------------------------------*/
1.79      cvs      3088: void PToCss (PresentationSetting settings, char *buffer, int len, Element el)
1.1       cvs      3089: {
1.76      cvs      3090:   ElementType         elType;
1.18      cvs      3091:   float               fval = 0;
                   3092:   unsigned short      red, green, blue;
                   3093:   int                 add_unit = 0;
                   3094:   unsigned int        unit, i;
                   3095:   ThotBool            real = FALSE;
                   3096: 
1.82      cvs      3097:   buffer[0] = EOS;
1.18      cvs      3098:   if (len < 40)
                   3099:     return;
                   3100: 
                   3101:   unit = settings->value.typed_data.unit;
                   3102:   if (settings->value.typed_data.real)
                   3103:     {
                   3104:       real = TRUE;
                   3105:       fval = (float) settings->value.typed_data.value;
                   3106:       fval /= 1000;
                   3107:     }
1.1       cvs      3108: 
1.18      cvs      3109:   switch (settings->type)
1.1       cvs      3110:     {
1.18      cvs      3111:     case PRVisibility:
                   3112:       break;
                   3113:     case PRFont:
                   3114:       switch (settings->value.typed_data.value)
                   3115:        {
                   3116:        case STYLE_FONT_HELVETICA:
1.82      cvs      3117:          strcpy (buffer, "font-family: helvetica");
1.18      cvs      3118:          break;
                   3119:        case STYLE_FONT_TIMES:
1.82      cvs      3120:          strcpy (buffer, "font-family: times");
1.18      cvs      3121:          break;
                   3122:        case STYLE_FONT_COURIER:
1.82      cvs      3123:          strcpy (buffer, "font-family: courier");
1.18      cvs      3124:          break;
                   3125:        }
                   3126:       break;
                   3127:     case PRStyle:
                   3128:       switch (settings->value.typed_data.value)
                   3129:        {
                   3130:        case STYLE_FONT_ROMAN:
1.82      cvs      3131:          strcpy (buffer, "font-style: normal");
1.18      cvs      3132:          break;
                   3133:        case STYLE_FONT_ITALICS:
1.82      cvs      3134:          strcpy (buffer, "font-style: italic");
1.18      cvs      3135:          break;
                   3136:        case STYLE_FONT_OBLIQUE:
1.82      cvs      3137:          strcpy (buffer, "font-style: oblique");
1.18      cvs      3138:          break;
1.20      cvs      3139:        }
                   3140:       break;
                   3141:     case PRWeight:
                   3142:       switch (settings->value.typed_data.value)
                   3143:        {
                   3144:        case STYLE_WEIGHT_BOLD:
1.82      cvs      3145:          strcpy (buffer, "font-weight: bold");
1.20      cvs      3146:          break;
                   3147:        case STYLE_WEIGHT_NORMAL:
1.82      cvs      3148:          strcpy (buffer, "font-weight: normal");
1.18      cvs      3149:          break;
                   3150:        }
                   3151:       break;
                   3152:     case PRSize:
                   3153:       if (unit == STYLE_UNIT_REL)
                   3154:        {
                   3155:          if (real)
                   3156:            {
1.82      cvs      3157:              sprintf (buffer, "font-size: %g", fval);
1.18      cvs      3158:              add_unit = 1;
                   3159:            }
                   3160:          else
                   3161:            switch (settings->value.typed_data.value)
                   3162:              {
                   3163:              case 1:
1.82      cvs      3164:                strcpy (buffer, "font-size: xx-small");
1.18      cvs      3165:                break;
                   3166:              case 2:
1.82      cvs      3167:                strcpy (buffer, "font-size: x-small");
1.18      cvs      3168:                break;
                   3169:              case 3:
1.82      cvs      3170:                strcpy (buffer, "font-size: small");
1.18      cvs      3171:                break;
                   3172:              case 4:
1.82      cvs      3173:                strcpy (buffer, "font-size: medium");
1.18      cvs      3174:                break;
                   3175:              case 5:
1.82      cvs      3176:                strcpy (buffer, "font-size: large");
1.18      cvs      3177:                break;
                   3178:              case 6:
1.82      cvs      3179:                strcpy (buffer, "font-size: x-large");
1.18      cvs      3180:                break;
                   3181:              case 7:
                   3182:              case 8:
                   3183:              case 9:
                   3184:              case 10:
                   3185:              case 11:
                   3186:              case 12:
1.82      cvs      3187:                strcpy (buffer, "font-size: xx-large");
1.18      cvs      3188:                break;
                   3189:              }
                   3190:        }
                   3191:       else
                   3192:        {
                   3193:          if (real)
1.82      cvs      3194:            sprintf (buffer, "font-size: %g", fval);
1.18      cvs      3195:          else
1.82      cvs      3196:            sprintf (buffer, "font-size: %d",
1.67      cvs      3197:                      settings->value.typed_data.value);
1.18      cvs      3198:          add_unit = 1;
                   3199:        }
                   3200:       break;
                   3201:     case PRUnderline:
                   3202:       switch (settings->value.typed_data.value)
                   3203:        {
                   3204:        case STYLE_UNDERLINE:
1.82      cvs      3205:          strcpy (buffer, "text-decoration: underline");
1.18      cvs      3206:          break;
                   3207:        case STYLE_OVERLINE:
1.82      cvs      3208:          strcpy (buffer, "text-decoration: overline");
1.18      cvs      3209:          break;
                   3210:        case STYLE_CROSSOUT:
1.82      cvs      3211:          strcpy (buffer, "text-decoration: line-through");
1.18      cvs      3212:          break;
                   3213:        }
                   3214:       break;
                   3215:     case PRIndent:
                   3216:       if (real)
1.82      cvs      3217:        sprintf (buffer, "text-indent: %g", fval);
1.18      cvs      3218:       else
1.82      cvs      3219:        sprintf (buffer, "text-indent: %d",
1.67      cvs      3220:                  settings->value.typed_data.value);
1.18      cvs      3221:       add_unit = 1;
                   3222:       break;
                   3223:     case PRLineSpacing:
                   3224:       if (real)
1.82      cvs      3225:        sprintf (buffer, "line-height: %g", fval);
1.1       cvs      3226:       else
1.82      cvs      3227:        sprintf (buffer, "line-height: %d",
1.67      cvs      3228:                  settings->value.typed_data.value);
1.18      cvs      3229:       add_unit = 1;
                   3230:       break;
                   3231:     case PRAdjust:
                   3232:       switch (settings->value.typed_data.value)
1.1       cvs      3233:        {
1.18      cvs      3234:        case STYLE_ADJUSTLEFT:
1.82      cvs      3235:          strcpy (buffer, "text-align: left");
1.18      cvs      3236:          break;
                   3237:        case STYLE_ADJUSTRIGHT:
1.82      cvs      3238:          strcpy (buffer, "text-align: right");
1.18      cvs      3239:          break;
                   3240:        case STYLE_ADJUSTCENTERED:
1.82      cvs      3241:          strcpy (buffer, "text-align: center");
1.18      cvs      3242:          break;
                   3243:        case STYLE_ADJUSTLEFTWITHDOTS:
1.82      cvs      3244:          strcpy (buffer, "text-align: left");
1.81      cvs      3245:          break;
                   3246:         case STYLE_ADJUSTJUSTIFY:
1.82      cvs      3247:          strcpy (buffer, "text-align: justify");
1.18      cvs      3248:          break;
1.1       cvs      3249:        }
1.18      cvs      3250:       break;
                   3251:     case PRHyphenate:
                   3252:       break;
                   3253:     case PRFillPattern:
                   3254:       break;
                   3255:     case PRBackground:
                   3256:       TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76      cvs      3257:       elType = TtaGetElementType(el);
                   3258: #ifdef GRAPHML
1.82      cvs      3259:       if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "GraphML") == 0)
                   3260:        sprintf (buffer, "fill: #%02X%02X%02X", red, green, blue);
1.67      cvs      3261:       else
1.76      cvs      3262: #endif /* GRAPHML */
1.82      cvs      3263:          sprintf (buffer, "background-color: #%02X%02X%02X", red, green,
1.67      cvs      3264:                   blue);
1.18      cvs      3265:       break;
                   3266:     case PRForeground:
                   3267:       TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76      cvs      3268:       elType = TtaGetElementType(el);
                   3269: #ifdef GRAPHML
1.82      cvs      3270:       if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "GraphML") == 0)
                   3271:        sprintf (buffer, "stroke: #%02X%02X%02X", red, green, blue);
1.67      cvs      3272:       else
1.76      cvs      3273: #endif /* GRAPHML */
1.82      cvs      3274:        sprintf (buffer, "color: #%02X%02X%02X", red, green, blue);
1.67      cvs      3275:       break;
                   3276:     case PRLineWeight:
1.76      cvs      3277:       elType = TtaGetElementType(el);
                   3278: #ifdef GRAPHML
1.82      cvs      3279:       if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "GraphML"))
1.76      cvs      3280: #endif /* GRAPHML */
1.69      cvs      3281:        {
                   3282:          if (real)
1.82      cvs      3283:            sprintf (buffer, "stroke-width: %g", fval);
1.69      cvs      3284:          else
1.82      cvs      3285:            sprintf (buffer, "stroke-width: %d",
1.69      cvs      3286:                      settings->value.typed_data.value);
                   3287:        }
1.67      cvs      3288:       add_unit = 1;
1.18      cvs      3289:       break;
1.67      cvs      3290: 
1.40      cvs      3291:     case PRMarginTop:
1.18      cvs      3292:       if (real)
1.82      cvs      3293:        sprintf (buffer, "marging-top: %g", fval);
1.18      cvs      3294:       else
1.82      cvs      3295:        sprintf (buffer, "marging-top: %d",
1.67      cvs      3296:                  settings->value.typed_data.value);
1.18      cvs      3297:       add_unit = 1;
                   3298:       break;
1.40      cvs      3299:     case PRMarginLeft:
1.18      cvs      3300:       if (real)
1.82      cvs      3301:        sprintf (buffer, "margin-left: %g", fval);
1.18      cvs      3302:       else
1.82      cvs      3303:        sprintf (buffer, "margin-left: %d",
1.67      cvs      3304:                  settings->value.typed_data.value);
1.18      cvs      3305:       add_unit = 1;
                   3306:       break;
                   3307:     case PRHeight:
                   3308:       if (real)
1.82      cvs      3309:        sprintf (buffer, "height: %g", fval);
1.18      cvs      3310:       else
1.82      cvs      3311:        sprintf (buffer, "height: %d", settings->value.typed_data.value);
1.18      cvs      3312:       add_unit = 1;
                   3313:       break;
                   3314:     case PRWidth:
                   3315:       if (real)
1.82      cvs      3316:        sprintf (buffer, "width: %g", fval);
1.1       cvs      3317:       else
1.82      cvs      3318:        sprintf (buffer, "width: %d", settings->value.typed_data.value);
1.18      cvs      3319:       add_unit = 1;
                   3320:       break;
                   3321:     case PRLine:
                   3322:       if (settings->value.typed_data.value == STYLE_INLINE)
1.82      cvs      3323:        strcpy (buffer, "display: inline");
1.18      cvs      3324:       else if (settings->value.typed_data.value == STYLE_NOTINLINE)
1.82      cvs      3325:        strcpy (buffer, "display: block");
1.18      cvs      3326:       break;
                   3327:     case PRBackgroundPicture:
                   3328:       if (settings->value.pointer != NULL)
1.82      cvs      3329:        sprintf (buffer, "background-image: url(%s)",
1.67      cvs      3330:                  (char*)(settings->value.pointer));
1.1       cvs      3331:       else
1.82      cvs      3332:        sprintf (buffer, "background-image: none");
1.18      cvs      3333:       break;
                   3334:     case PRPictureMode:
                   3335:       switch (settings->value.typed_data.value)
1.1       cvs      3336:        {
1.18      cvs      3337:        case STYLE_REALSIZE:
1.82      cvs      3338:          sprintf (buffer, "background-repeat: no-repeat");
1.18      cvs      3339:          break;
                   3340:        case STYLE_REPEAT:
1.82      cvs      3341:          sprintf (buffer, "background-repeat: repeat");
1.18      cvs      3342:          break;
                   3343:        case STYLE_VREPEAT:
1.82      cvs      3344:          sprintf (buffer, "background-repeat: repeat-y");
1.18      cvs      3345:          break;
                   3346:        case STYLE_HREPEAT:
1.82      cvs      3347:          sprintf (buffer, "background-repeat: repeat-x");
1.18      cvs      3348:          break;
1.1       cvs      3349:        }
1.18      cvs      3350:       break;
                   3351:     default:
                   3352:       break;
1.1       cvs      3353:     }
                   3354: 
1.18      cvs      3355:   if (add_unit)
1.1       cvs      3356:     {
1.18      cvs      3357:       /* add the unit string to the CSS string */
                   3358:       for (i = 0; i < NB_UNITS; i++)
1.1       cvs      3359:        {
1.18      cvs      3360:          if (CSSUnitNames[i].unit == unit)
1.1       cvs      3361:            {
1.82      cvs      3362:              strcat (buffer, CSSUnitNames[i].sign);
1.18      cvs      3363:              break;
1.1       cvs      3364:            }
                   3365:        }
                   3366:     }
                   3367: }
                   3368: 
                   3369: /*----------------------------------------------------------------------
1.59      cvs      3370:    ParseHTMLSpecificStyle: parse and apply a CSS Style string.
1.18      cvs      3371:    This function must be called when a specific style is applied to an
                   3372:    element.
1.68      cvs      3373:    The parameter isCSS is 1 when the specific presentation should be
                   3374:    translated into a CSS rule, 0 if it should be translated into a
                   3375:    presentation attribute.
1.1       cvs      3376:   ----------------------------------------------------------------------*/
1.79      cvs      3377: void  ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.78      cvs      3378:                              int isCSS, ThotBool destroy)
1.1       cvs      3379: {
                   3380:    PresentationContext context;
                   3381:    ElementType         elType;
1.14      cvs      3382:    ThotBool            isHTML;
1.1       cvs      3383: 
                   3384:    /*  A rule applying to BODY is really meant to address HTML */
                   3385:    elType = TtaGetElementType (el);
1.89      cvs      3386: 
1.86      cvs      3387:    /* store the current line for eventually reported errors */
                   3388:    LineNumber = TtaGetElementLineNumber (el);
1.89      cvs      3389:    if (destroy)
                   3390:      /* no reported errors */
                   3391:      ParsedDoc = 0;
                   3392:    else if (ParsedDoc != doc)
                   3393:      {
                   3394:        /* update the context for reported errors */
                   3395:        ParsedDoc = doc;
                   3396:        DocURL = DocumentURLs[doc];
                   3397:      }
1.82      cvs      3398:    isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
1.1       cvs      3399:    /* create the context of the Specific presentation driver */
                   3400:    context = TtaGetSpecificStyleContext (doc);
                   3401:    if (context == NULL)
                   3402:      return;
                   3403:    context->type = elType.ElTypeNum;
1.68      cvs      3404:    context->cssLevel = isCSS;
1.1       cvs      3405:    context->destroy = destroy;
                   3406:    /* Call the parser */
                   3407:    ParseCSSRule (el, NULL, (PresentationContext) context, cssRule, NULL, isHTML);
                   3408:    /* free the context */
                   3409:    TtaFreeMemory(context);
                   3410: }
                   3411: 
1.68      cvs      3412: 
1.1       cvs      3413: /*----------------------------------------------------------------------
1.59      cvs      3414:    ParseGenericSelector: Create a generic context for a given 
1.1       cvs      3415:    selector string. If the selector is made of multiple comma- 
                   3416:    separated selector items, it parses them one at a time and  
                   3417:    return the end of the selector string to be handled or NULL 
                   3418:   ----------------------------------------------------------------------*/
1.79      cvs      3419: static char *ParseGenericSelector (char *selector, char *cssRule,
                   3420:                                   GenericContext ctxt, Document doc,
                   3421:                                   CSSInfoPtr css)
                   3422: {
                   3423:   ElementType        elType;
                   3424:   PSchema            tsch;
1.91      cvs      3425:   /*AttributeType      attrType;*/
1.79      cvs      3426:   char               sel[MAX_ANCESTORS * 50];
                   3427:   char              *deb, *cur;
                   3428:   char              *structName;
                   3429:   char              *names[MAX_ANCESTORS];
                   3430:   char              *ids[MAX_ANCESTORS];
                   3431:   char              *classes[MAX_ANCESTORS];
                   3432:   char              *pseudoclasses[MAX_ANCESTORS];
                   3433:   char              *attrs[MAX_ANCESTORS];
                   3434:   char              *attrvals[MAX_ANCESTORS];
1.91      cvs      3435:   char              *ptr;
                   3436:   int                i, j, k, max;
                   3437:   int                att, maxAttr;
1.79      cvs      3438:   ThotBool           isHTML;
                   3439:   ThotBool           level;
1.1       cvs      3440: 
1.82      cvs      3441:   sel[0] = EOS;
1.1       cvs      3442:   for (i = 0; i < MAX_ANCESTORS; i++)
                   3443:     {
1.25      cvs      3444:       names[i] = NULL;
                   3445:       ids[i] = NULL;
                   3446:       classes[i] = NULL;
                   3447:       pseudoclasses[i] = NULL;
                   3448:       attrs[i] = NULL;
                   3449:       attrvals[i] = NULL;
                   3450: 
                   3451:       ctxt->name[i] = 0;
                   3452:       ctxt->names_nb[i] = 0;
                   3453:       ctxt->attrType[i] = 0;
                   3454:       ctxt->attrText[i] = NULL;
1.1       cvs      3455:     }
1.25      cvs      3456:   ctxt->box = 0;
                   3457:   ctxt->type = 0;
1.68      cvs      3458:   /* the priority level of the rule depends on the selector */
                   3459:   ctxt->cssLevel = 0;
1.25      cvs      3460:   
1.82      cvs      3461:   selector = SkipBlanksAndComments (selector);
1.27      cvs      3462:   cur = &sel[0];
1.25      cvs      3463:   max = 0; /* number of loops */
1.1       cvs      3464:   while (1)
                   3465:     {
1.85      cvs      3466:       /* point to the following word in sel[] */
1.27      cvs      3467:       deb = cur;
1.25      cvs      3468:       /* copy an item of the selector into sel[] */
1.1       cvs      3469:       /* put one word in the sel buffer */
1.82      cvs      3470:       while (*selector != EOS && *selector != ',' &&
                   3471:              *selector != '.' && *selector != ':' &&
                   3472:              *selector != '#' && !TtaIsBlank (selector))
1.50      cvs      3473:             *cur++ = *selector++;
1.82      cvs      3474:       *cur++ = EOS; /* close the first string  in sel[] */
                   3475:       if (deb[0] != EOS)
1.27      cvs      3476:        names[0] = deb;
1.25      cvs      3477:       else
1.27      cvs      3478:        names[0] = NULL;
                   3479:       classes[0] = NULL;
                   3480:       pseudoclasses[0] = NULL;
                   3481:       ids[0] = NULL;
                   3482:       attrs[0] = NULL;
                   3483:       attrvals[0] = NULL;
1.25      cvs      3484: 
1.27      cvs      3485:       /* now names[0] points to the beginning of the parsed item
1.25      cvs      3486:         and cur to the next chain to be parsed */
1.82      cvs      3487:       if (*selector == ':' || *selector == '.' || *selector == '#')
1.85      cvs      3488:        /* point to the following word in sel[] */
                   3489:        deb = cur;
1.1       cvs      3490: 
1.82      cvs      3491:       if (*selector == '.')
1.1       cvs      3492:        {
                   3493:          selector++;
1.82      cvs      3494:          while (*selector != EOS && *selector != ',' &&
                   3495:                 *selector != '.' && *selector != ':' &&
                   3496:                 !TtaIsBlank (selector))
1.1       cvs      3497:            *cur++ = *selector++;
1.86      cvs      3498:          /* close the word */
                   3499:          *cur++ = EOS;
1.85      cvs      3500:          /* point to the class in sel[] if it's valid name */
1.86      cvs      3501:          if (deb[0] <= 64)
                   3502:            CSSParseError ("Invalid class", deb);
                   3503:          else
1.85      cvs      3504:            classes[0] = deb;
1.1       cvs      3505:        }
1.82      cvs      3506:       else if (*selector == ':')
1.1       cvs      3507:        {
                   3508:          selector++;
1.82      cvs      3509:          while (*selector != EOS && *selector != ',' &&
                   3510:              *selector != '.' && *selector != ':' &&
                   3511:              !TtaIsBlank (selector))
1.50      cvs      3512:             *cur++ = *selector++;
1.86      cvs      3513:          /* close the word */
                   3514:          *cur++ = EOS;
1.85      cvs      3515:          /* point to the pseudoclass in sel[] if it's valid name */
1.86      cvs      3516:          if (deb[0] <= 64)
                   3517:            CSSParseError ("Invalid pseudoclass", deb);
                   3518:          else
1.85      cvs      3519:            pseudoclasses[0]= deb;
1.1       cvs      3520:        }
1.82      cvs      3521:       else if (*selector == '#')
1.1       cvs      3522:        {
                   3523:          selector++;
1.82      cvs      3524:          while (*selector != EOS && *selector != ',' &&
                   3525:              *selector != '.' && *selector != ':' &&
                   3526:              !TtaIsBlank (selector))
1.50      cvs      3527:             *cur++ = *selector++;
1.86      cvs      3528:          /* close the word */
                   3529:          *cur++ = EOS;
1.85      cvs      3530:          /* point to the attribute in sel[] if it's valid name */
1.86      cvs      3531:          if (deb[0] <= 64)
                   3532:            CSSParseError ("Invalid id", deb);
                   3533:          else
1.85      cvs      3534:            ids[0] = deb;
1.1       cvs      3535:        }
1.82      cvs      3536:       else if (*selector == '[')
1.1       cvs      3537:        {
1.25      cvs      3538:          selector++;
1.85      cvs      3539:          while (*selector != EOS && *selector != ']' &&
                   3540:                 *selector != '=' && *selector != '~')
1.25      cvs      3541:            *cur++ = *selector++;
1.86      cvs      3542:          /* close the word */
                   3543:          *cur++ = EOS;
1.85      cvs      3544:          /* point to the attribute in sel[] if it's valid name */
1.86      cvs      3545:          if (deb[0] <= 64)
                   3546:            CSSParseError ("Invalid attribute", deb);
                   3547:          else
1.85      cvs      3548:            attrs[0] = deb;
                   3549:          if (*selector == '=')
1.25      cvs      3550:            {
1.85      cvs      3551:              /* look for a value "xxxx" */
1.82      cvs      3552:              while (*selector != EOS && *selector != ']' && *selector != '"')
1.85      cvs      3553:                *cur++ = *selector++;
                   3554:              /* there is a value */
1.86      cvs      3555:              if (*selector == EOS)
                   3556:                CSSParseError ("Invalid attribute value", deb);
                   3557:              else
1.25      cvs      3558:                {
                   3559:                  /* we are now parsing the attribute value */
1.27      cvs      3560:                  attrvals[0] = cur;
1.25      cvs      3561:                  selector++;
1.82      cvs      3562:                  while (*selector != EOS && *selector != '"')
1.25      cvs      3563:                    *cur++ = *selector++;
1.82      cvs      3564:                  if (*selector != EOS)
1.25      cvs      3565:                    selector++;
                   3566:                }
                   3567:            }
1.82      cvs      3568:          *cur++ = EOS;
1.1       cvs      3569:        }
                   3570: 
1.82      cvs      3571:       selector = SkipBlanksAndComments (selector);
1.25      cvs      3572:       /* is it a multi-level selector? */
1.82      cvs      3573:       if (*selector == EOS)
1.1       cvs      3574:        /* end of the selector */
                   3575:        break;
1.82      cvs      3576:       else if (*selector == ',')
1.1       cvs      3577:        {
                   3578:          /* end of the current selector */
                   3579:          selector++;
                   3580:          break;
                   3581:        }
1.25      cvs      3582:       else
                   3583:        {
                   3584:          /* shifts the list to make room for the new name */
                   3585:          max++; /* a new level in ancestor tables */
                   3586:          if (max == MAX_ANCESTORS)
                   3587:            /* abort the CSS parsing */
                   3588:            return (selector);
                   3589:          for (i = max; i > 0; i--)
                   3590:            {
                   3591:              names[i] = names[i - 1];
                   3592:              ids[i] = ids[i - 1];
                   3593:              classes[i] = classes[i - 1];
                   3594:              attrs[i] = attrs[i - 1];
                   3595:              attrvals[i] = attrvals[i - 1];
                   3596:              pseudoclasses[i] = pseudoclasses[i - 1];
                   3597:            }
                   3598:        }
1.1       cvs      3599:     }
                   3600: 
                   3601:   /* Now set up the context block */
1.25      cvs      3602:   i = 0;
                   3603:   k = 0;
                   3604:   j = 0;
1.35      cvs      3605:   maxAttr = 0;
1.91      cvs      3606:   /* default schema name */
                   3607:   ptr = "HTML";
1.25      cvs      3608:   while (i <= max)
                   3609:     {
                   3610:       if (names[i])
                   3611:        {
                   3612:          /* get the new element type of this name */
                   3613:          GIType (names[i], &elType, doc);
                   3614:          if (i == 0)
                   3615:            {
                   3616:              /* Store the element type */
                   3617:              ctxt->type = elType.ElTypeNum;
1.32      cvs      3618:              ctxt->name[0] = elType.ElTypeNum;
                   3619:              ctxt->names_nb[0] = 0;
1.25      cvs      3620:              ctxt->schema = elType.ElSSchema;
1.91      cvs      3621:              ptr = TtaGetSSchemaName (elType.ElSSchema);
1.27      cvs      3622:              k++;
1.25      cvs      3623:            }
                   3624:          else if (elType.ElTypeNum != 0)
                   3625:            {
                   3626:              /* look at the current context to see if the type is already
                   3627:                 stored */
                   3628:              j = 0;
1.32      cvs      3629:              while (j < k && ctxt->name[j] != elType.ElTypeNum)
1.25      cvs      3630:                j++;
                   3631:              if (j == k)
                   3632:                {
                   3633:                  /* add a new entry */
                   3634:                  k++;
                   3635:                  ctxt->name[j] = elType.ElTypeNum;
                   3636:                  if (j != 0)
                   3637:                  ctxt->names_nb[j] = 1;
                   3638:                }
                   3639:              else
                   3640:                /* increment the number of ancestor levels */
                   3641:                ctxt->names_nb[j]++;
                   3642:            }
                   3643:          else
                   3644:            {
                   3645:              /* add a new entry */
                   3646:              j = k;
                   3647:              k++;
                   3648:            }
                   3649:        }
1.1       cvs      3650: 
1.25      cvs      3651:       /* store attributes information */
                   3652:       if (classes[i])
                   3653:        {
                   3654:          ctxt->attrText[j] = classes[i];
1.91      cvs      3655:          if (!strcmp (ptr, "GraphML"))
                   3656:            ctxt->attrType[j] = GraphML_ATTR_class;
                   3657:          else if (!strcmp (ptr, "MathML"))
                   3658:            ctxt->attrType[j] = MathML_ATTR_class;
                   3659:          else
                   3660:            ctxt->attrType[j] = HTML_ATTR_Class;
1.79      cvs      3661:          /* add a new entry */
1.80      cvs      3662:          maxAttr = i + 1;
1.25      cvs      3663:        }
1.79      cvs      3664:       if (pseudoclasses[i])
1.25      cvs      3665:        {
                   3666:          ctxt->attrText[j] = pseudoclasses[i];
1.91      cvs      3667:          if (!strcmp (ptr, "GraphML"))
                   3668:            ctxt->attrType[j] = GraphML_ATTR_PseudoClass;
                   3669:          else if (!strcmp (ptr, "MathML"))
                   3670:            ctxt->attrType[j] = MathML_ATTR_PseudoClass;
                   3671:          else
                   3672:            ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.79      cvs      3673:          /* add a new entry */
1.80      cvs      3674:          maxAttr = i + 1;
1.25      cvs      3675:        }
1.79      cvs      3676:       if (ids[i])
1.25      cvs      3677:        {
                   3678:          ctxt->attrText[j] = ids[i];
1.91      cvs      3679:          if (!strcmp (ptr, "GraphML"))
                   3680:            ctxt->attrType[j] = GraphML_ATTR_id;
                   3681:          else if (!strcmp (ptr, "MathML"))
                   3682:            ctxt->attrType[j] = MathML_ATTR_id;
                   3683:          else
                   3684:            ctxt->attrType[j] = HTML_ATTR_ID;
1.80      cvs      3685:          /* add a new entry */
                   3686:          maxAttr = i + 1;
1.25      cvs      3687:        }
1.79      cvs      3688:       if (attrs[i])
1.25      cvs      3689:        {
1.91      cvs      3690:          if (!strcmp (ptr, "GraphML"))
                   3691:            MapXMLAttribute (GRAPH_TYPE, attrs[i], names[i], &level, doc, &att);
                   3692:          else if (!strcmp (ptr, "MathML"))
                   3693:            MapXMLAttribute (MATH_TYPE, attrs[i], names[i], &level, doc, &att);
                   3694:          else
                   3695:            MapXMLAttribute (XHTML_TYPE, attrs[i], names[i], &level, doc, &att);
1.25      cvs      3696:          ctxt->attrText[j] = attrvals[i];
1.91      cvs      3697:          /* we should pass also the attribute schema in the context */
                   3698:          ctxt->attrType[j] = att;
1.80      cvs      3699:          maxAttr = i + 1;
1.25      cvs      3700:        }
                   3701:       i++;
1.1       cvs      3702:     }
                   3703: 
1.25      cvs      3704:   /* sort the list of ancestors by name order */
                   3705:   max = k;
                   3706:   i = 1;
                   3707:   while (i < max)
1.28      cvs      3708:     {
                   3709:       for (k = i + 1; k < max; k++)
                   3710:        if (ctxt->name[i] > ctxt->name[k])
                   3711:          {
                   3712:            j = ctxt->name[i];
                   3713:            ctxt->name[i] = ctxt->name[k];
                   3714:            ctxt->name[k] = j;
                   3715:            j = ctxt->names_nb[i];
                   3716:            ctxt->names_nb[i] = ctxt->names_nb[k];
                   3717:            ctxt->names_nb[k] = j;
                   3718:            j = ctxt->attrType[i];
                   3719:            ctxt->attrType[i] = ctxt->attrType[k];
                   3720:            ctxt->attrType[k] = j;
                   3721:            cur = ctxt->attrText[i];
                   3722:            ctxt->attrText[i] = ctxt->attrText[k];
                   3723:            ctxt->attrText[k] = cur;
                   3724:          }
                   3725:       i++;
                   3726:     }
1.84      cvs      3727: 
1.25      cvs      3728:   /* Get the schema name of the main element */
                   3729:   if (ctxt->schema == NULL)
1.1       cvs      3730:     ctxt->schema = TtaGetDocumentSSchema (doc);
1.82      cvs      3731:   isHTML = (strcmp (TtaGetSSchemaName (ctxt->schema), "HTML") == 0);
1.1       cvs      3732:   tsch = GetPExtension (doc, ctxt->schema, css);
                   3733:   structName = TtaGetSSchemaName (ctxt->schema);
                   3734:   if (cssRule)
                   3735:     ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
                   3736:   return (selector);
                   3737: }
                   3738: 
                   3739: /*----------------------------------------------------------------------
1.73      cvs      3740:    ParseStyleDeclaration: parse a style declaration    
                   3741:    stored in the style element of a document                       
1.59      cvs      3742:    We expect the style string to be of the form:                   
1.1       cvs      3743:    [                                                                
                   3744:    e.g: pinky, awful { color: pink, font-family: helvetica }        
                   3745:   ----------------------------------------------------------------------*/
1.79      cvs      3746: static void  ParseStyleDeclaration (Element el, char *cssRule, Document doc,
                   3747:                                    CSSInfoPtr css, ThotBool destroy)
1.1       cvs      3748: {
1.79      cvs      3749:   GenericContext      ctxt;
                   3750:   char               *decl_end;
                   3751:   char               *sel_end;
                   3752:   char               *selector;
                   3753:   char                saved1;
                   3754:   char                saved2;
1.1       cvs      3755: 
                   3756:   /* separate the selectors string */
1.82      cvs      3757:   cssRule = SkipBlanksAndComments (cssRule);
1.1       cvs      3758:   decl_end = cssRule;
1.82      cvs      3759:   while (*decl_end != EOS && *decl_end != '{')
1.1       cvs      3760:     decl_end++;
1.82      cvs      3761:   if (*decl_end == EOS)
1.86      cvs      3762:     {
                   3763:       CSSParseError ("Invalid selector", cssRule);
                   3764:       return;
                   3765:     }
1.1       cvs      3766:   /* verify and clean the selector string */
                   3767:   sel_end = decl_end - 1;
1.82      cvs      3768:   while (*sel_end == SPACE || *sel_end == BSPACE ||
                   3769:         *sel_end == EOL || *sel_end == CR)
1.1       cvs      3770:     sel_end--;
                   3771:   sel_end++;
                   3772:   saved1 = *sel_end;
1.82      cvs      3773:   *sel_end = EOS;
1.1       cvs      3774:   selector = cssRule;
                   3775: 
                   3776:   /* now, deal with the content ... */
                   3777:   decl_end++;
                   3778:   cssRule = decl_end;
1.82      cvs      3779:   while (*decl_end != EOS && *decl_end != '}')
1.1       cvs      3780:     decl_end++;
1.82      cvs      3781:   if (*decl_end == EOS)
1.1       cvs      3782:     {
1.86      cvs      3783:       CSSParseError ("Invalid selector", cssRule);
1.1       cvs      3784:       return;
                   3785:     }
                   3786:   saved2 = *decl_end;
1.82      cvs      3787:   *decl_end = EOS;
1.1       cvs      3788: 
                   3789:   /*
                   3790:    * parse the style attribute string and install the corresponding
                   3791:    * presentation attributes on the new element
                   3792:    */
                   3793:   ctxt = TtaGetGenericStyleContext (doc);
                   3794:   if (ctxt == NULL)
                   3795:     return;
                   3796:   ctxt->destroy = destroy;
                   3797: 
1.82      cvs      3798:   while ((selector != NULL) && (*selector != EOS))
1.25      cvs      3799:     selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css);
1.1       cvs      3800:   TtaFreeMemory (ctxt);
                   3801: 
                   3802:   /* restore the string to its original form ! */
                   3803:   *sel_end = saved1;
                   3804:   *decl_end = saved2;
                   3805: }
                   3806: 
                   3807: /************************************************************************
                   3808:  *                                                                     *  
                   3809:  *     EVALUATION FUNCTIONS / CASCADING AND OVERLOADING                *
                   3810:  *                                                                     *  
                   3811:  ************************************************************************/
                   3812: 
                   3813: /*----------------------------------------------------------------------
1.59      cvs      3814:    IsImplicitClassName: return wether the Class name is an        
1.1       cvs      3815:    implicit one, eg "H1" or "H2 EM" meaning it's a GI name       
                   3816:    or an HTML context name.                                      
                   3817:   ----------------------------------------------------------------------*/
1.79      cvs      3818: int         IsImplicitClassName (char *class, Document doc)
1.1       cvs      3819: {
1.79      cvs      3820:    char         name[200];
                   3821:    char        *cur = name;
                   3822:    char        *first; 
                   3823:    char         save;
                   3824:    SSchema      schema;
1.1       cvs      3825: 
                   3826:    /* make a local copy */
1.82      cvs      3827:    strncpy (name, class, 199);
1.1       cvs      3828:    name[199] = 0;
                   3829: 
                   3830:    /* loop looking if each word is a GI */
                   3831:    while (*cur != 0)
                   3832:      {
                   3833:        first = cur;
                   3834:        cur = SkipWord (cur);
                   3835:        save = *cur;
                   3836:        *cur = 0;
                   3837:        schema = NULL;
                   3838:        if (MapGI (first, &schema, doc) == -1)
                   3839:          {
                   3840:             return (0);
                   3841:          }
                   3842:        *cur = save;
1.82      cvs      3843:        cur = SkipBlanksAndComments (cur);
1.1       cvs      3844:      }
                   3845:    return (1);
                   3846: }
                   3847: 
                   3848: /************************************************************************
                   3849:  *                                                                     *  
1.59      cvs      3850:  *  Functions Needed for support of HTML 3.2: translate to CSS equiv   *
1.1       cvs      3851:  *                                                                     *  
                   3852:  ************************************************************************/
                   3853: 
                   3854: /*----------------------------------------------------------------------
1.59      cvs      3855:    HTMLSetBackgroundColor:
1.1       cvs      3856:   ----------------------------------------------------------------------*/
1.79      cvs      3857: void    HTMLSetBackgroundColor (Document doc, Element el, char *color)
1.1       cvs      3858: {
1.79      cvs      3859:    char             css_command[100];
1.1       cvs      3860: 
1.82      cvs      3861:    sprintf (css_command, "background-color: %s", color);
1.68      cvs      3862:    ParseHTMLSpecificStyle (el, css_command, doc, 1, FALSE);
1.1       cvs      3863: }
                   3864: 
                   3865: /*----------------------------------------------------------------------
1.59      cvs      3866:    HTMLSetBackgroundImage:
1.1       cvs      3867:    repeat = repeat value
                   3868:    image = url of background image
                   3869:   ----------------------------------------------------------------------*/
1.79      cvs      3870: void HTMLSetBackgroundImage (Document doc, Element el, int repeat, char *image)
1.1       cvs      3871: {
1.79      cvs      3872:    char           css_command[400];
1.1       cvs      3873: 
                   3874:    /******* check buffer overflow ********/
1.82      cvs      3875:    sprintf (css_command, "background-image: url(%s); background-repeat: ", image);
1.1       cvs      3876:    if (repeat == STYLE_REPEAT)
1.82      cvs      3877:      strcat (css_command, "repeat");
1.1       cvs      3878:    else if (repeat == STYLE_HREPEAT)
1.82      cvs      3879:      strcat (css_command, "repeat-x");
1.1       cvs      3880:    else if (repeat == STYLE_VREPEAT)
1.82      cvs      3881:      strcat (css_command, "repeat-y");
1.1       cvs      3882:    else
1.82      cvs      3883:      strcat (css_command, "no-repeat");
1.68      cvs      3884:    ParseHTMLSpecificStyle (el, css_command, doc, 1, FALSE);
1.1       cvs      3885: }
                   3886: 
                   3887: /*----------------------------------------------------------------------
1.59      cvs      3888:    HTMLSetForegroundColor:                                        
1.1       cvs      3889:   ----------------------------------------------------------------------*/
1.79      cvs      3890: void   HTMLSetForegroundColor (Document doc, Element el, char *color)
1.1       cvs      3891: {
1.79      cvs      3892:    char           css_command[100];
1.1       cvs      3893: 
1.82      cvs      3894:    sprintf (css_command, "color: %s", color);
1.68      cvs      3895:    ParseHTMLSpecificStyle (el, css_command, doc, 1, FALSE);
1.1       cvs      3896: }
                   3897: 
                   3898: /*----------------------------------------------------------------------
1.59      cvs      3899:    HTMLResetBackgroundColor:                                      
1.1       cvs      3900:   ----------------------------------------------------------------------*/
                   3901: void                HTMLResetBackgroundColor (Document doc, Element el)
                   3902: {
1.79      cvs      3903:    char           css_command[100];
1.1       cvs      3904: 
1.82      cvs      3905:    sprintf (css_command, "background: red");
1.68      cvs      3906:    ParseHTMLSpecificStyle (el, css_command, doc, 1, TRUE);
1.1       cvs      3907: }
                   3908: 
                   3909: /*----------------------------------------------------------------------
1.59      cvs      3910:    HTMLResetBackgroundImage:                                      
1.1       cvs      3911:   ----------------------------------------------------------------------*/
                   3912: void                HTMLResetBackgroundImage (Document doc, Element el)
                   3913: {
1.79      cvs      3914:    char           css_command[1000];
1.1       cvs      3915: 
1.82      cvs      3916:    sprintf (css_command, "background-image: url(xx); background-repeat: repeat");
1.68      cvs      3917:    ParseHTMLSpecificStyle (el, css_command, doc, 1, TRUE);
1.1       cvs      3918: }
                   3919: 
                   3920: /*----------------------------------------------------------------------
1.59      cvs      3921:    HTMLResetForegroundColor:                                      
1.1       cvs      3922:   ----------------------------------------------------------------------*/
                   3923: void                HTMLResetForegroundColor (Document doc, Element el)
                   3924: {
1.79      cvs      3925:    char           css_command[100];
1.1       cvs      3926: 
1.36      cvs      3927:    /* it's not necessary to well know the current color but it must be valid */
1.82      cvs      3928:    sprintf (css_command, "color: red");
1.68      cvs      3929:    ParseHTMLSpecificStyle (el, css_command, doc, 1, TRUE);
1.1       cvs      3930: }
                   3931: 
                   3932: /*----------------------------------------------------------------------
1.59      cvs      3933:    HTMLSetAlinkColor:                                             
1.1       cvs      3934:   ----------------------------------------------------------------------*/
1.79      cvs      3935: void                HTMLSetAlinkColor (Document doc, char *color)
1.1       cvs      3936: {
1.79      cvs      3937:    char           css_command[100];
1.1       cvs      3938: 
1.82      cvs      3939:    sprintf (css_command, "a:link { color: %s }", color);
1.1       cvs      3940:    ApplyCSSRules (NULL, css_command, doc, FALSE);
                   3941: }
                   3942: 
                   3943: /*----------------------------------------------------------------------
1.59      cvs      3944:    HTMLSetAactiveColor:                                           
1.1       cvs      3945:   ----------------------------------------------------------------------*/
1.79      cvs      3946: void                HTMLSetAactiveColor (Document doc, char *color)
1.1       cvs      3947: {
1.79      cvs      3948:    char           css_command[100];
1.1       cvs      3949: 
1.82      cvs      3950:    sprintf (css_command, "a:active { color: %s }", color);
1.1       cvs      3951:    ApplyCSSRules (NULL, css_command, doc, FALSE);
                   3952: }
                   3953: 
                   3954: /*----------------------------------------------------------------------
1.59      cvs      3955:    HTMLSetAvisitedColor:                                          
1.1       cvs      3956:   ----------------------------------------------------------------------*/
1.79      cvs      3957: void                HTMLSetAvisitedColor (Document doc, char *color)
1.1       cvs      3958: {
1.79      cvs      3959:    char           css_command[100];
1.1       cvs      3960: 
1.82      cvs      3961:    sprintf (css_command, "a:visited { color: %s }", color);
1.1       cvs      3962:    ApplyCSSRules (NULL, css_command, doc, FALSE);
                   3963: }
                   3964: 
                   3965: /*----------------------------------------------------------------------
1.59      cvs      3966:    HTMLResetAlinkColor:                                           
1.1       cvs      3967:   ----------------------------------------------------------------------*/
                   3968: void                HTMLResetAlinkColor (Document doc)
                   3969: {
1.79      cvs      3970:    char           css_command[100];
1.1       cvs      3971: 
1.82      cvs      3972:    sprintf (css_command, "a:link { color: red }");
1.1       cvs      3973:    ApplyCSSRules (NULL, css_command, doc, TRUE);
                   3974: }
                   3975: 
                   3976: /*----------------------------------------------------------------------
1.59      cvs      3977:    HTMLResetAactiveColor:                                                 
1.1       cvs      3978:   ----------------------------------------------------------------------*/
                   3979: void                HTMLResetAactiveColor (Document doc)
                   3980: {
1.79      cvs      3981:    char           css_command[100];
1.1       cvs      3982: 
1.82      cvs      3983:    sprintf (css_command, "a:active { color: red }");
1.1       cvs      3984:    ApplyCSSRules (NULL, css_command, doc, TRUE);
                   3985: }
                   3986: 
                   3987: /*----------------------------------------------------------------------
1.59      cvs      3988:    HTMLResetAvisitedColor:                                        
1.1       cvs      3989:   ----------------------------------------------------------------------*/
                   3990: void                HTMLResetAvisitedColor (Document doc)
                   3991: {
1.79      cvs      3992:    char           css_command[100];
1.1       cvs      3993: 
1.82      cvs      3994:    sprintf (css_command, "a:visited { color: red }");
1.1       cvs      3995:    ApplyCSSRules (NULL, css_command, doc, TRUE);
                   3996: }
                   3997: 
                   3998: /*----------------------------------------------------------------------
1.73      cvs      3999:   ApplyCSSRules: parse a CSS Style description stored in the
1.1       cvs      4000:   header of a HTML document.
                   4001:   ----------------------------------------------------------------------*/
1.79      cvs      4002: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1       cvs      4003: {
                   4004:   CSSInfoPtr        css;
                   4005: 
                   4006:   css = SearchCSS (doc, NULL);
                   4007:   if (css == NULL)
                   4008:     /* create the document css */
                   4009:     css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, NULL, NULL);
                   4010:   ParseStyleDeclaration (el, cssRule, doc, css, destroy); 
                   4011: }
                   4012: 
                   4013: /*----------------------------------------------------------------------
1.59      cvs      4014:    ReadCSSRules:  is the front-end function called by the HTML parser
1.1       cvs      4015:    when detecting a <STYLE TYPE="text/css"> indicating it's the
                   4016:    beginning of a CSS fragment or when reading a file .css.
                   4017:   
                   4018:    The CSS parser has to handle <!-- ... --> constructs used to
                   4019:    prevent prehistoric browser from displaying the CSS as a text
                   4020:    content. It will stop on any sequence "<x" where x is different
                   4021:    from ! and will return x as to the caller. Theorically x should
                   4022:    be equal to / for the </STYLE> end of style.
                   4023: 
                   4024:    The parameter doc gives the document tree that contains CSS information.
                   4025:    The parameter docRef gives the document to which CSS are to be applied.
                   4026:    This function uses the current css context or creates it. It's able
1.23      cvs      4027:    to work on the given buffer or call GetNextChar to read the parsed
1.1       cvs      4028:    file.
1.86      cvs      4029:    Parameter numberOfLinesRead indicates the number of lines already
                   4030:    read in the file.
1.1       cvs      4031:    Parameter withUndo indicates whether the changes made in the document
                   4032:    structure and content have to be registered in the Undo queue or not
                   4033:   ----------------------------------------------------------------------*/
1.86      cvs      4034: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer,
                   4035:                   int numberOfLinesRead, ThotBool withUndo)
1.1       cvs      4036: {
1.6       cvs      4037:   DisplayMode         dispMode;
1.82      cvs      4038:   char                c;
                   4039:   char               *cssRule, *base;
1.19      cvs      4040:   int                 index;
1.1       cvs      4041:   int                 CSSindex;
                   4042:   int                 CSScomment;
                   4043:   int                 import;
                   4044:   int                 openRule;
1.93      vatton   4045:   int                 newlines;
1.14      cvs      4046:   ThotBool            HTMLcomment;
                   4047:   ThotBool            toParse, eof;
1.36      cvs      4048:   ThotBool            ignoreMedia, media;
1.88      cvs      4049:   ThotBool            noRule, ignoreImport;
1.1       cvs      4050: 
                   4051:   CSScomment = MAX_CSS_LENGTH;
                   4052:   HTMLcomment = FALSE;
                   4053:   CSSindex = 0;
                   4054:   toParse = FALSE;
                   4055:   noRule = FALSE;
1.36      cvs      4056:   media =  FALSE;
1.88      cvs      4057:   ignoreImport = FALSE;
1.1       cvs      4058:   ignoreMedia = FALSE;
                   4059:   import = MAX_CSS_LENGTH;
                   4060:   eof = FALSE;
                   4061:   openRule = 0;
1.82      cvs      4062:   c = SPACE;
1.1       cvs      4063:   index = 0;
1.93      vatton   4064:   /* number of new lines parsed */
                   4065:   newlines = 0;
1.6       cvs      4066:   /* avoid too many redisplay */
                   4067:   dispMode = TtaGetDisplayMode (docRef);
                   4068:   if (dispMode == DisplayImmediately)
                   4069:     TtaSetDisplayMode (docRef, DeferredDisplay);
1.18      cvs      4070: 
                   4071:   /* look for the CSS context */
                   4072:   if (css == NULL)
                   4073:     css = SearchCSS (docRef, NULL);
                   4074:   if (css == NULL)
                   4075:     css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, NULL, NULL);
1.1       cvs      4076: 
1.86      cvs      4077:   /* register parsed CSS file and the document to which CSS are to be applied */
                   4078:   ParsedDoc = docRef;
                   4079:   if (css->url)
                   4080:     DocURL = css->url;
                   4081:   else
                   4082:     /* the CSS source in within the document itself */
                   4083:     DocURL = DocumentURLs[docRef];
                   4084:   LineNumber = numberOfLinesRead + 1;
1.93      vatton   4085:   NewLineSkipped = 0;
1.82      cvs      4086:   while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
                   4087:     {
                   4088:       c = buffer[index++];
                   4089:       eof = (c == EOS);
                   4090:       CSSbuffer[CSSindex] = c;
                   4091:       if (CSScomment == MAX_CSS_LENGTH ||
                   4092:          c == '*' || c == '/' || c == '<')
                   4093:        {
                   4094:          /* we're not within a comment or we're parsing * or / */
                   4095:          switch (c)
                   4096:            {
                   4097:            case '@': /* perhaps an import primitive */
                   4098:              import = CSSindex;
                   4099:              break;
                   4100:            case ';':
                   4101:              if (import != MAX_CSS_LENGTH && !media)
                   4102:                { 
                   4103:                  if (strncasecmp (&CSSbuffer[import+1], "import", 6))
                   4104:                    /* it's not an import */
                   4105:                    import = MAX_CSS_LENGTH;
                   4106:                  /* save the text */
                   4107:                  noRule = TRUE;
                   4108:                }
                   4109:              break;
                   4110:            case '*':
                   4111:              if (CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
                   4112:                  CSSbuffer[CSSindex - 1] == '/')
                   4113:                /* start a comment */
                   4114:                CSScomment = CSSindex - 1;
                   4115:              break;
                   4116:            case '/':
                   4117:              if (CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
                   4118:                  CSSbuffer[CSSindex - 1] == '*')
                   4119:                {
                   4120:                  /* close a comment:and ignore its contents */
                   4121:                  CSSindex = CSScomment - 1; /* will be incremented later */
                   4122:                  CSScomment = MAX_CSS_LENGTH;
1.93      vatton   4123:                  /* clean up the buffer */
                   4124:                  if (newlines &&CSSindex >= 0)
                   4125:                    while (CSSbuffer[CSSindex] == SPACE ||
                   4126:                           CSSbuffer[CSSindex] == BSPACE ||
                   4127:                           CSSbuffer[CSSindex] == EOL ||
                   4128:                           CSSbuffer[CSSindex] == TAB ||
                   4129:                           CSSbuffer[CSSindex] == __CR__)
                   4130:                      {
                   4131:                        if ( CSSbuffer[CSSindex] == EOL)
                   4132:                          {
                   4133:                            LineNumber ++;
                   4134:                            newlines --;
                   4135:                          }
                   4136:                      CSSindex--;
                   4137:                      }
1.82      cvs      4138:                }
                   4139:              else if (CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
                   4140:                       CSSbuffer[CSSindex - 1] ==  '<')
                   4141:                {
                   4142:                  /* this is the closing tag ! */
                   4143:                  CSSindex -= 2; /* remove </ from the CSS string */
                   4144:                  noRule = TRUE;
                   4145:                } 
                   4146:              break;
                   4147:            case '<':
                   4148:              if (CSScomment == MAX_CSS_LENGTH)
                   4149:                {
                   4150:                  /* only if we're not parsing a comment */
                   4151:                  c = buffer[index++];
                   4152:                  eof = (c == EOS);
                   4153:                  if (c == '!')
                   4154:                    {
                   4155:                      /* CSS within an HTML comment */
                   4156:                      HTMLcomment = TRUE;
                   4157:                      CSSindex++;
                   4158:                      CSSbuffer[CSSindex] = c;
                   4159:                    }
                   4160:                  else if (c == EOS)
                   4161:                    CSSindex++;
                   4162:                }
                   4163:              break;
                   4164:            case '-':
                   4165:              if (CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
                   4166:                  HTMLcomment)
                   4167:                /* CSS within an HTML comment */
                   4168:                noRule = TRUE;
                   4169:              break;
                   4170:            case '>':
                   4171:              if (HTMLcomment)
                   4172:                noRule = TRUE;
                   4173:              break;
                   4174:            case ' ':
                   4175:              if (import != MAX_CSS_LENGTH && openRule == 0)
                   4176:                media = !strncmp (&CSSbuffer[import+1], "media", 5);
                   4177:              break;
                   4178:            case '{':
                   4179:              openRule++;
                   4180:              if (import != MAX_CSS_LENGTH && openRule == 1 && media)
                   4181:                {
                   4182:                  /* is it the screen concerned? */
                   4183:                  CSSbuffer[CSSindex+1] = EOS;
                   4184:                  if (TtaIsPrinting ())
                   4185:                    base = strstr (&CSSbuffer[import], "print");
                   4186:                  else
                   4187:                    base = strstr (&CSSbuffer[import], "screen");
                   4188:                  if (base == NULL)
                   4189:                    ignoreMedia = TRUE;
                   4190:                  noRule = TRUE;
                   4191:                }
                   4192:              break;
                   4193:            case '}':
                   4194:              openRule--;
                   4195:              if (import != MAX_CSS_LENGTH && openRule == 0)
                   4196:                {
                   4197:                  import = MAX_CSS_LENGTH;
                   4198:                  noRule = TRUE;
                   4199:                  ignoreMedia = FALSE;
                   4200:                  media = FALSE;
                   4201:                }
                   4202:              else
                   4203:                toParse = TRUE;
                   4204:              break;
                   4205:            default:
1.86      cvs      4206:              if (c == EOL)
1.93      vatton   4207:                newlines++;
1.82      cvs      4208:              break;
                   4209:            }
                   4210:         }
1.93      vatton   4211:       else if (c == EOL)
                   4212:        LineNumber++;
1.82      cvs      4213:       if (c != CR)
                   4214:        CSSindex++;
                   4215: 
                   4216:       if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
                   4217:        /* we're still parsing a comment: remove the text comment */
                   4218:        CSSindex = CSScomment;
                   4219: 
                   4220:       if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
                   4221:        {
                   4222:          CSSbuffer[CSSindex] = EOS;
                   4223:          /* parse a not empty string */
                   4224:          if (CSSindex > 0)
                   4225:            {
1.50      cvs      4226:               /* apply CSS rule if it's not just a saving of text */
                   4227:               if (!noRule && !ignoreMedia)
1.88      cvs      4228:                {
                   4229:                  /* future import rules must be ignored */
                   4230:                  ignoreImport = TRUE;
                   4231:                  ParseStyleDeclaration (NULL, CSSbuffer, docRef, css, FALSE);
1.93      vatton   4232:                  LineNumber += newlines;
                   4233:                  newlines = 0;
                   4234:                  NewLineSkipped = 0;
1.88      cvs      4235:                }
1.82      cvs      4236:               else if (import != MAX_CSS_LENGTH &&
                   4237:                       !strncasecmp (&CSSbuffer[import+1], "import", 6))
                   4238:                {
                   4239:                  /* import section */
                   4240:                  cssRule = &CSSbuffer[import+7];
                   4241:                  cssRule = TtaSkipBlanks (cssRule);
1.93      vatton   4242:                  /* save the current line number */
                   4243:                  newlines += LineNumber;
1.82      cvs      4244:                  if (!strncasecmp (cssRule, "url", 3))
                   4245:                    {
1.50      cvs      4246:                       cssRule = &cssRule[3];
1.82      cvs      4247:                       cssRule = TtaSkipBlanks (cssRule);
                   4248:                       if (*cssRule == '(')
                   4249:                        {
                   4250:                          cssRule++;
                   4251:                          cssRule = TtaSkipBlanks (cssRule);
                   4252:                          base = cssRule;
                   4253:                          while (*cssRule != EOS && *cssRule != ')')
                   4254:                            cssRule++;
                   4255:                          *cssRule = EOS;
1.88      cvs      4256:                          if (!ignoreImport)
                   4257:                            LoadStyleSheet (base, docRef, NULL, css, css->media[docRef]);
1.82      cvs      4258:                        }
                   4259:                    }
1.87      cvs      4260:                  else if (*cssRule == '"')
                   4261:                    {
1.88      cvs      4262:                      /*
                   4263:                        Do we have to accept single quotes?
                   4264:                        Double quotes are acceted here.
                   4265:                        Escaped quotes are not handled. See function SkipQuotedString
                   4266:                      */
1.87      cvs      4267:                      cssRule++;
                   4268:                      cssRule = TtaSkipBlanks (cssRule);
                   4269:                      base = cssRule;
                   4270:                      while (*cssRule != EOS && *cssRule != '"')
                   4271:                        cssRule++;
                   4272:                      *cssRule = EOS;
1.88      cvs      4273:                      if (!ignoreImport)
                   4274:                        LoadStyleSheet (base, docRef, NULL, css, css->media[docRef]);
1.82      cvs      4275:                    }
1.93      vatton   4276:                  /* restore the number of lines */
                   4277:                  LineNumber = newlines;
                   4278:                  newlines = 0;
1.82      cvs      4279:                  import = MAX_CSS_LENGTH;
                   4280:                }
1.93      vatton   4281:                
1.82      cvs      4282:            }
                   4283:          toParse = FALSE;
                   4284:          noRule = FALSE;
                   4285:          CSSindex = 0;
1.50      cvs      4286:         }
1.82      cvs      4287:     }
1.6       cvs      4288:   /* restore the display mode */
                   4289:   if (dispMode == DisplayImmediately)
1.82      cvs      4290:     TtaSetDisplayMode (docRef, dispMode);
1.86      cvs      4291: 
                   4292:   /* Prepare the context for style attributes */
                   4293:   DocURL = DocumentURLs[docRef];
                   4294:   LineNumber = -1;
1.1       cvs      4295:   return (c);
                   4296: }
1.89      cvs      4297: 

Webmaster