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

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

Webmaster