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

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

Webmaster