khtml Library API Documentation

cssstyleselector.cpp

00001 
00025 #include "css/cssstyleselector.h"
00026 #include "rendering/render_style.h"
00027 #include "css/css_stylesheetimpl.h"
00028 #include "css/css_ruleimpl.h"
00029 #include "css/css_valueimpl.h"
00030 #include "css/csshelper.h"
00031 #include "rendering/render_object.h"
00032 #include "html/html_documentimpl.h"
00033 #include "html/html_elementimpl.h"
00034 #include "xml/dom_elementimpl.h"
00035 #include "dom/css_rule.h"
00036 #include "dom/css_value.h"
00037 #include "khtml_factory.h"
00038 #include "khtmlpart_p.h"
00039 using namespace khtml;
00040 using namespace DOM;
00041 
00042 #include "css/cssproperties.h"
00043 #include "css/cssvalues.h"
00044 
00045 #include "misc/khtmllayout.h"
00046 #include "khtml_settings.h"
00047 #include "misc/htmlhashes.h"
00048 #include "misc/helper.h"
00049 #include "misc/loader.h"
00050 
00051 #include "rendering/font.h"
00052 
00053 #include "khtmlview.h"
00054 #include "khtml_part.h"
00055 
00056 #include <kstandarddirs.h>
00057 #include <kcharsets.h>
00058 #include <kglobal.h>
00059 #include <kconfig.h>
00060 #include <qfile.h>
00061 #include <qvaluelist.h>
00062 #include <qstring.h>
00063 #include <qtooltip.h>
00064 #include <kdebug.h>
00065 #include <kurl.h>
00066 #include <assert.h>
00067 #include <qpaintdevicemetrics.h>
00068 #include <stdlib.h>
00069 
00070 #define HANDLE_INHERIT(prop, Prop) \
00071 if (isInherit) \
00072 {\
00073     style->set##Prop(parentStyle->prop());\
00074     return;\
00075 }
00076 
00077 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
00078 HANDLE_INHERIT(prop, Prop) \
00079 else if (isInitial) \
00080     style->set##Prop(RenderStyle::initial##Prop());
00081 
00082 #define HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \
00083 HANDLE_INHERIT(prop, Prop) \
00084 else if (isInitial) \
00085     style->set##Prop(RenderStyle::initial##Value());
00086 
00087 #define HANDLE_INHERIT_COND(propID, prop, Prop) \
00088 if (id == propID) \
00089 {\
00090     style->set##Prop(parentStyle->prop());\
00091     return;\
00092 }
00093 
00094 #define HANDLE_INITIAL_COND(propID, Prop) \
00095 if (id == propID) \
00096 {\
00097     style->set##Prop(RenderStyle::initial##Prop());\
00098     return;\
00099 }
00100 
00101 #define HANDLE_INITIAL_COND_WITH_VALUE(propID, Prop, Value) \
00102 if (id == propID) \
00103 {\
00104     style->set##Prop(RenderStyle::initial##Value());\
00105     return;\
00106 }
00107 
00108 namespace khtml {
00109 
00110 CSSStyleSelectorList *CSSStyleSelector::s_defaultStyle;
00111 CSSStyleSelectorList *CSSStyleSelector::s_defaultQuirksStyle;
00112 CSSStyleSelectorList *CSSStyleSelector::s_defaultPrintStyle;
00113 CSSStyleSheetImpl *CSSStyleSelector::s_defaultSheet;
00114 RenderStyle* CSSStyleSelector::styleNotYetAvailable;
00115 CSSStyleSheetImpl *CSSStyleSelector::s_quirksSheet;
00116 
00117 enum PseudoState { PseudoUnknown, PseudoNone, PseudoLink, PseudoVisited};
00118 static PseudoState pseudoState;
00119 
00120 
00121 CSSStyleSelector::CSSStyleSelector( DocumentImpl* doc, QString userStyleSheet, StyleSheetListImpl *styleSheets,
00122                                     const KURL &url, bool _strictParsing )
00123 {
00124     KHTMLView* view = doc->view();
00125 
00126     init(view ? view->part()->settings() : 0);
00127 
00128     strictParsing = _strictParsing;
00129     m_medium = view ? view->mediaType() : QString("all");
00130 
00131     selectors = 0;
00132     selectorCache = 0;
00133     properties = 0;
00134     userStyle = 0;
00135     userSheet = 0;
00136     paintDeviceMetrics = doc->paintDeviceMetrics();
00137 
00138     if(paintDeviceMetrics) // this may be null, not everyone uses khtmlview (Niko)
00139         computeFontSizes(paintDeviceMetrics, view ? view->part()->zoomFactor() : 100);
00140 
00141     if ( !userStyleSheet.isEmpty() ) {
00142         userSheet = new DOM::CSSStyleSheetImpl(doc);
00143         userSheet->parseString( DOMString( userStyleSheet ) );
00144 
00145         userStyle = new CSSStyleSelectorList();
00146         userStyle->append( userSheet, m_medium );
00147     }
00148 
00149     // add stylesheets from document
00150     authorStyle = new CSSStyleSelectorList();
00151 
00152 
00153     QPtrListIterator<StyleSheetImpl> it( styleSheets->styleSheets );
00154     for ( ; it.current(); ++it ) {
00155         if ( it.current()->isCSSStyleSheet() ) {
00156             authorStyle->append( static_cast<CSSStyleSheetImpl*>( it.current() ), m_medium );
00157         }
00158     }
00159 
00160     buildLists();
00161 
00162     //kdDebug( 6080 ) << "number of style sheets in document " << authorStyleSheets.count() << endl;
00163     //kdDebug( 6080 ) << "CSSStyleSelector: author style has " << authorStyle->count() << " elements"<< endl;
00164 
00165     KURL u = url;
00166 
00167     u.setQuery( QString::null );
00168     u.setRef( QString::null );
00169     encodedurl.file = u.url();
00170     int pos = encodedurl.file.findRev('/');
00171     encodedurl.path = encodedurl.file;
00172     if ( pos > 0 ) {
00173     encodedurl.path.truncate( pos );
00174     encodedurl.path += '/';
00175     }
00176     u.setPath( QString::null );
00177     encodedurl.host = u.url();
00178 
00179     //kdDebug() << "CSSStyleSelector::CSSStyleSelector encoded url " << encodedurl.path << endl;
00180 }
00181 
00182 CSSStyleSelector::CSSStyleSelector( CSSStyleSheetImpl *sheet )
00183 {
00184     init(0L);
00185 
00186     KHTMLView *view = sheet->doc()->view();
00187     m_medium = view ? view->mediaType() : "screen";
00188 
00189     authorStyle = new CSSStyleSelectorList();
00190     authorStyle->append( sheet, m_medium );
00191 }
00192 
00193 void CSSStyleSelector::init(const KHTMLSettings* _settings)
00194 {
00195     element = 0;
00196     settings = _settings;
00197     paintDeviceMetrics = 0;
00198     propsToApply = (CSSOrderedProperty **)malloc(128*sizeof(CSSOrderedProperty *));
00199     pseudoProps = (CSSOrderedProperty **)malloc(128*sizeof(CSSOrderedProperty *));
00200     propsToApplySize = 128;
00201     pseudoPropsSize = 128;
00202     if(!s_defaultStyle) loadDefaultStyle(settings);
00203 
00204     defaultStyle = s_defaultStyle;
00205     defaultPrintStyle = s_defaultPrintStyle;
00206     defaultQuirksStyle = s_defaultQuirksStyle;
00207 }
00208 
00209 CSSStyleSelector::~CSSStyleSelector()
00210 {
00211     clearLists();
00212     delete authorStyle;
00213     delete userStyle;
00214     delete userSheet;
00215     free(propsToApply);
00216     free(pseudoProps);
00217 }
00218 
00219 void CSSStyleSelector::addSheet( CSSStyleSheetImpl *sheet )
00220 {
00221     KHTMLView *view = sheet->doc()->view();
00222     m_medium = view ? view->mediaType() : "screen";
00223     authorStyle->append( sheet, m_medium );
00224 }
00225 
00226 void CSSStyleSelector::loadDefaultStyle(const KHTMLSettings *s)
00227 {
00228     if(s_defaultStyle) return;
00229 
00230     {
00231     QFile f(locate( "data", "khtml/css/html4.css" ) );
00232     f.open(IO_ReadOnly);
00233 
00234     QCString file( f.size()+1 );
00235     int readbytes = f.readBlock( file.data(), f.size() );
00236     f.close();
00237     if ( readbytes >= 0 )
00238         file[readbytes] = '\0';
00239 
00240     QString style = QString::fromLatin1( file.data() );
00241     if(s)
00242         style += s->settingsToCSS();
00243     DOMString str(style);
00244 
00245     s_defaultSheet = new DOM::CSSStyleSheetImpl((DOM::CSSStyleSheetImpl * ) 0);
00246     s_defaultSheet->parseString( str );
00247 
00248     // Collect only strict-mode rules.
00249     s_defaultStyle = new CSSStyleSelectorList();
00250     s_defaultStyle->append( s_defaultSheet, "screen" );
00251 
00252     s_defaultPrintStyle = new CSSStyleSelectorList();
00253     s_defaultPrintStyle->append( s_defaultSheet, "print" );
00254     }
00255     {
00256     QFile f(locate( "data", "khtml/css/quirks.css" ) );
00257     f.open(IO_ReadOnly);
00258 
00259     QCString file( f.size()+1 );
00260     int readbytes = f.readBlock( file.data(), f.size() );
00261     f.close();
00262     if ( readbytes >= 0 )
00263         file[readbytes] = '\0';
00264 
00265     QString style = QString::fromLatin1( file.data() );
00266     DOMString str(style);
00267 
00268     s_quirksSheet = new DOM::CSSStyleSheetImpl((DOM::CSSStyleSheetImpl * ) 0);
00269     s_quirksSheet->parseString( str );
00270 
00271     // Collect only quirks-mode rules.
00272     s_defaultQuirksStyle = new CSSStyleSelectorList();
00273     s_defaultQuirksStyle->append( s_quirksSheet, "screen" );
00274     }
00275 
00276     //kdDebug() << "CSSStyleSelector: default style has " << defaultStyle->count() << " elements"<< endl;
00277 }
00278 
00279 void CSSStyleSelector::clear()
00280 {
00281     delete s_defaultStyle;
00282     delete s_defaultQuirksStyle;
00283     delete s_defaultPrintStyle;
00284     delete s_defaultSheet;
00285     delete styleNotYetAvailable;
00286     s_defaultStyle = 0;
00287     s_defaultQuirksStyle = 0;
00288     s_defaultPrintStyle = 0;
00289     s_defaultSheet = 0;
00290     styleNotYetAvailable = 0;
00291 }
00292 
00293 void CSSStyleSelector::reparseConfiguration()
00294 {
00295     // nice leak, but best we can do right now. hopefully its only rare.
00296     s_defaultStyle = 0;
00297     s_defaultQuirksStyle = 0;
00298     s_defaultPrintStyle = 0;
00299     s_defaultSheet = 0;
00300 }
00301 
00302 #define MAXFONTSIZES 9
00303 
00304 void CSSStyleSelector::computeFontSizes(QPaintDeviceMetrics* paintDeviceMetrics,  int zoomFactor)
00305 {
00306     computeFontSizesFor(paintDeviceMetrics, zoomFactor, m_fontSizes, false);
00307     computeFontSizesFor(paintDeviceMetrics, zoomFactor, m_fixedFontSizes, true);
00308 }
00309 
00310 void CSSStyleSelector::computeFontSizesFor(QPaintDeviceMetrics* paintDeviceMetrics, int zoomFactor, QValueList<int>& fontSizes, bool isFixed)
00311 {
00312 #ifdef APPLE_CHANGES
00313     // We don't want to scale the settings by the dpi.
00314     const float toPix = 1;
00315 #else
00316     Q_UNUSED( isFixed );
00317 
00318     // ### get rid of float / double
00319     float toPix = paintDeviceMetrics->logicalDpiY()/72.;
00320     if (toPix  < 96./72.) toPix = 96./72.;
00321 #endif // ######### fix isFixed code again.
00322 
00323     fontSizes.clear();
00324     float scale = 1.0;
00325     static const float fontFactors[] =      {3./5., 3./4., 8./9., 1., 6./5., 3./2., 2., 3., 4.};
00326     static const float smallFontFactors[] = {3./4., 5./6., 8./9., 1., 6./5., 3./2., 2., 3., 4.};
00327     float mediumFontSize, minFontSize, factor;
00328     if (!khtml::printpainter) {
00329         scale *= zoomFactor / 100.0;
00330 #ifdef APPLE_CHANGES
00331     if (isFixed)
00332         mediumFontSize = settings->mediumFixedFontSize() * toPix;
00333     else
00334 #endif
00335         mediumFontSize = settings->mediumFontSize() * toPix;
00336         minFontSize = settings->minFontSize() * toPix;
00337     }
00338     else {
00339         // ## depending on something / configurable ?
00340         mediumFontSize = 12;
00341         minFontSize = 6;
00342     }
00343     const float* factors = scale*mediumFontSize >= 12.5 ? fontFactors : smallFontFactors;
00344     for ( int i = 0; i < MAXFONTSIZES; i++ ) {
00345         factor = scale*factors[i];
00346         fontSizes << int(KMAX( mediumFontSize*factor +.5f, minFontSize));
00347         //kdDebug( 6080 ) << "index: " << i << " factor: " << factors[i] << " font pix size: " << int(KMAX( mediumFontSize*factor +.5f, minFontSize)) << endl;
00348     }
00349 }
00350 
00351 #undef MAXFONTSIZES
00352 
00353 static inline void bubbleSort( CSSOrderedProperty **b, CSSOrderedProperty **e )
00354 {
00355     while( b < e ) {
00356     bool swapped = false;
00357         CSSOrderedProperty **y = e+1;
00358     CSSOrderedProperty **x = e;
00359         CSSOrderedProperty **swappedPos = 0;
00360     do {
00361         if ( !((**(--x)) < (**(--y))) ) {
00362         swapped = true;
00363                 swappedPos = x;
00364                 CSSOrderedProperty *tmp = *y;
00365                 *y = *x;
00366                 *x = tmp;
00367         }
00368     } while( x != b );
00369     if ( !swapped ) break;
00370         b = swappedPos + 1;
00371     }
00372 }
00373 
00374 RenderStyle *CSSStyleSelector::styleForElement(ElementImpl *e)
00375 {
00376     if (!e->getDocument()->haveStylesheetsLoaded() || !e->getDocument()->view()) {
00377         if (!styleNotYetAvailable) {
00378             styleNotYetAvailable = new RenderStyle();
00379             styleNotYetAvailable->setDisplay(NONE);
00380             styleNotYetAvailable->ref();
00381         }
00382         return styleNotYetAvailable;
00383     }
00384 
00385     // set some variables we will need
00386     pseudoState = PseudoUnknown;
00387 
00388     element = e;
00389     parentNode = e->parentNode();
00390     parentStyle = ( parentNode && parentNode->renderer()) ? parentNode->renderer()->style() : 0;
00391     view = element->getDocument()->view();
00392     part = view->part();
00393     settings = part->settings();
00394     paintDeviceMetrics = element->getDocument()->paintDeviceMetrics();
00395 
00396     style = new RenderStyle();
00397     if( parentStyle )
00398         style->inheritFrom( parentStyle );
00399     else
00400     parentStyle = style;
00401 
00402     unsigned int numPropsToApply = 0;
00403     unsigned int numPseudoProps = 0;
00404 
00405     // try to sort out most style rules as early as possible.
00406     int cssTagId = (e->id() & NodeImpl_IdLocalMask);
00407     int smatch = 0;
00408     int schecked = 0;
00409 
00410     for ( unsigned int i = 0; i < selectors_size; i++ ) {
00411     int tag = selectors[i]->tag & NodeImpl_IdLocalMask;
00412     if ( cssTagId == tag || tag == 0xffff ) {
00413         ++schecked;
00414 
00415         checkSelector( i, e );
00416 
00417         if ( selectorCache[i].state == Applies ) {
00418         ++smatch;
00419 
00420 //      qDebug("adding property" );
00421         for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 )
00422             for ( unsigned int j = 0; j < (unsigned int )selectorCache[i].props[p+1]; ++j ) {
00423                         if (numPropsToApply >= propsToApplySize ) {
00424                             propsToApplySize *= 2;
00425                 propsToApply = (CSSOrderedProperty **)realloc( propsToApply, propsToApplySize*sizeof( CSSOrderedProperty * ) );
00426             }
00427             propsToApply[numPropsToApply++] = properties[selectorCache[i].props[p]+j];
00428             }
00429         } else if ( selectorCache[i].state == AppliesPseudo ) {
00430         for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 )
00431             for ( unsigned int j = 0; j < (unsigned int) selectorCache[i].props[p+1]; ++j ) {
00432                         if (numPseudoProps >= pseudoPropsSize ) {
00433                             pseudoPropsSize *= 2;
00434                 pseudoProps = (CSSOrderedProperty **)realloc( pseudoProps, pseudoPropsSize*sizeof( CSSOrderedProperty * ) );
00435             }
00436             pseudoProps[numPseudoProps++] = properties[selectorCache[i].props[p]+j];
00437             properties[selectorCache[i].props[p]+j]->pseudoId = (RenderStyle::PseudoId) selectors[i]->pseudoId;
00438             }
00439         }
00440     }
00441     else
00442         selectorCache[i].state = Invalid;
00443 
00444     }
00445 
00446     // inline style declarations, after all others. non css hints
00447     // count as author rules, and come before all other style sheets, see hack in append()
00448     numPropsToApply = addInlineDeclarations( e, e->m_styleDecls, numPropsToApply );
00449 
00450 //     qDebug( "styleForElement( %s )", e->tagName().string().latin1() );
00451 //     qDebug( "%d selectors, %d checked,  %d match,  %d properties ( of %d )",
00452 //      selectors_size, schecked, smatch, numPropsToApply, properties_size );
00453 
00454     bubbleSort( propsToApply, propsToApply+numPropsToApply-1 );
00455     bubbleSort( pseudoProps, pseudoProps+numPseudoProps-1 );
00456 
00457     // we can't apply style rules without a view() and a part. This
00458     // tends to happen on delayed destruction of widget Renderobjects
00459     if ( part ) {
00460         fontDirty = false;
00461 
00462         if (numPropsToApply ) {
00463             CSSStyleSelector::style = style;
00464             for (unsigned int i = 0; i < numPropsToApply; ++i) {
00465         if ( fontDirty && propsToApply[i]->priority >= (1 << 30) ) {
00466             // we are past the font properties, time to update to the
00467             // correct font
00468 #ifdef APPLE_CHANGES
00469             checkForGenericFamilyChange(style, parentStyle);
00470 #endif
00471             CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics );
00472             fontDirty = false;
00473         }
00474         DOM::CSSProperty *prop = propsToApply[i]->prop;
00475 //      if (prop->m_id == CSS_PROP__KONQ_USER_INPUT) kdDebug(6080) << "El: "<<e->nodeName().string() << " user-input: "<<((CSSPrimitiveValueImpl *)prop->value())->getIdent() << endl;
00476 //      if (prop->m_id == CSS_PROP_TEXT_TRANSFORM) kdDebug(6080) << "El: "<<e->nodeName().string() << endl;
00477                 applyRule( prop->m_id, prop->value() );
00478         }
00479         if ( fontDirty ) {
00480 #ifdef APPLE_CHANGES
00481             checkForGenericFamilyChange(style, parentStyle);
00482 #endif
00483         CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics );
00484             }
00485         }
00486 
00487         // Clean up our style object's display and text decorations (among other fixups).
00488         adjustRenderStyle(style, e);
00489 
00490         if ( numPseudoProps ) {
00491         fontDirty = false;
00492             //qDebug("%d applying %d pseudo props", e->cssTagId(), pseudoProps->count() );
00493             for (unsigned int i = 0; i < numPseudoProps; ++i) {
00494         if ( fontDirty && pseudoProps[i]->priority >= (1 << 30) ) {
00495             // we are past the font properties, time to update to the
00496             // correct font
00497             //We have to do this for all pseudo styles
00498             RenderStyle *pseudoStyle = style->pseudoStyle;
00499             while ( pseudoStyle ) {
00500             pseudoStyle->htmlFont().update( paintDeviceMetrics );
00501             pseudoStyle = pseudoStyle->pseudoStyle;
00502             }
00503             fontDirty = false;
00504         }
00505 
00506                 RenderStyle *pseudoStyle;
00507                 pseudoStyle = style->getPseudoStyle(pseudoProps[i]->pseudoId);
00508                 if (!pseudoStyle)
00509                 {
00510                     pseudoStyle = style->addPseudoStyle(pseudoProps[i]->pseudoId);
00511                     if (pseudoStyle)
00512                         pseudoStyle->inheritFrom( style );
00513                 }
00514 
00515                 RenderStyle* oldStyle = style;
00516                 RenderStyle* oldParentStyle = parentStyle;
00517                 parentStyle = style;
00518         style = pseudoStyle;
00519                 if ( pseudoStyle ) {
00520             DOM::CSSProperty *prop = pseudoProps[i]->prop;
00521             applyRule( prop->m_id, prop->value() );
00522         }
00523                 style = oldStyle;
00524                 parentStyle = oldParentStyle;
00525             }
00526 
00527         if ( fontDirty ) {
00528         RenderStyle *pseudoStyle = style->pseudoStyle;
00529         while ( pseudoStyle ) {
00530             pseudoStyle->htmlFont().update( paintDeviceMetrics );
00531             pseudoStyle = pseudoStyle->pseudoStyle;
00532         }
00533         }
00534         }
00535     }
00536 
00537     // Now adjust all our pseudo-styles.
00538     RenderStyle *pseudoStyle = style->pseudoStyle;
00539     while (pseudoStyle) {
00540         adjustRenderStyle(pseudoStyle, 0);
00541         pseudoStyle = pseudoStyle->pseudoStyle;
00542     }
00543 
00544     // Now return the style.
00545     return style;
00546 }
00547 
00548 void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, DOM::ElementImpl *e)
00549 {
00550      // Cache our original display.
00551      style->setOriginalDisplay(style->display());
00552 
00553     if (style->display() != NONE) {
00554         // If we have a <td> that specifies a float property, in quirks mode we just drop the float
00555         // property.
00556         // Sites also commonly use display:inline/block on <td>s and <table>s.  In quirks mode we force
00557         // these tags to retain their display types.
00558         if (!strictParsing && e) {
00559             if (e->id() == ID_TD) {
00560                 style->setDisplay(TABLE_CELL);
00561                 style->setFloating(FNONE);
00562             }
00563 //             else if (e->id() == ID_TABLE)
00564 //                 style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
00565         }
00566 
00567         // Mutate the display to BLOCK or TABLE for certain cases, e.g., if someone attempts to
00568         // position or float an inline, compact, or run-in.  Cache the original display, since it
00569         // may be needed for positioned elements that have to compute their static normal flow
00570         // positions.  We also force inline-level roots to be block-level.
00571         if (style->display() != BLOCK && style->display() != TABLE /*&& style->display() != BOX*/ &&
00572             (style->position() == ABSOLUTE || style->position() == FIXED || style->floating() != FNONE ||
00573              (e && e->getDocument()->documentElement() == e))) {
00574              if (style->display() == INLINE_TABLE)
00575                  style->setDisplay(TABLE);
00576 //             else if (style->display() == INLINE_BOX)
00577 //                 style->setDisplay(BOX);
00578             else if (style->display() == LIST_ITEM) {
00579                 // It is a WinIE bug that floated list items lose their bullets, so we'll emulate the quirk,
00580                 // but only in quirks mode.
00581                 if (!strictParsing && style->floating() != FNONE)
00582                     style->setDisplay(BLOCK);
00583             }
00584             else
00585                 style->setDisplay(BLOCK);
00586         }
00587 
00588         // After performing the display mutation, check table rows.  We do not honor position:relative on
00589         // table rows. This has been established in CSS2.1 (and caused a crash in containingBlock() on
00590         // some sites).
00591         // Likewise, disallow relative positioning on table sections.
00592         if ( style->position() == RELATIVE && (style->display() > INLINE_TABLE && style->display() < TABLE_COLUMN_GROUP) )
00593             style->setPosition(STATIC);
00594     }
00595 
00596     // Frames and framesets never honor position:relative or position:absolute.  This is necessary to
00597     // fix a crash where a site tries to position these objects.
00598     if ( e ) {
00599         // ignore display: none for <frame>
00600         if ( e->id() == ID_FRAME ) {
00601             style->setPosition( STATIC );
00602             style->setDisplay( BLOCK );
00603         }
00604         else if ( e->id() == ID_FRAMESET ) {
00605             style->setPosition( STATIC );
00606         }
00607     }
00608 
00609     // Finally update our text decorations in effect, but don't allow text-decoration to percolate through
00610     // tables, inline blocks, inline tables, or run-ins.
00611     if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN
00612         || style->display() == INLINE_BLOCK /*|| style->display() == INLINE_BOX*/)
00613         style->setTextDecorationsInEffect(style->textDecoration());
00614     else
00615         style->addToTextDecorationsInEffect(style->textDecoration());
00616 }
00617 
00618 unsigned int CSSStyleSelector::addInlineDeclarations(DOM::ElementImpl* e,
00619                                                      DOM::CSSStyleDeclarationImpl *decl,
00620                                                      unsigned int numProps)
00621 {
00622     CSSStyleDeclarationImpl* addDecls = 0;
00623 #ifdef APPLE_CHANGES
00624     if (e->id() == ID_TD || e->id() == ID_TH)     // For now only TableCellElement implements the
00625         addDecls = e->getAdditionalStyleDecls();  // virtual function for shared cell rules.
00626 #else
00627     Q_UNUSED( e );
00628 #endif
00629 
00630     if (!decl && !addDecls)
00631         return numProps;
00632 
00633     QPtrList<CSSProperty>* values = decl ? decl->values() : 0;
00634     QPtrList<CSSProperty>* addValues = addDecls ? addDecls->values() : 0;
00635     if (!values && !addValues)
00636         return numProps;
00637 
00638     int firstLen = values ? values->count() : 0;
00639     int secondLen = addValues ? addValues->count() : 0;
00640     int totalLen = firstLen + secondLen;
00641 
00642     if (inlineProps.size() < (uint)totalLen)
00643         inlineProps.resize(totalLen + 1);
00644 
00645     if (numProps + totalLen >= propsToApplySize ) {
00646         propsToApplySize += propsToApplySize;
00647         propsToApply = (CSSOrderedProperty **)realloc( propsToApply, propsToApplySize*sizeof( CSSOrderedProperty * ) );
00648     }
00649 
00650     CSSOrderedProperty *array = (CSSOrderedProperty *)inlineProps.data();
00651     for(int i = 0; i < totalLen; i++)
00652     {
00653         if (i == firstLen)
00654             values = addValues;
00655 
00656         CSSProperty *prop = values->at(i >= firstLen ? i - firstLen : i);
00657     Source source = Inline;
00658 
00659         if( prop->m_bImportant ) source = InlineImportant;
00660     if( prop->nonCSSHint ) source = NonCSSHint;
00661 
00662     bool first;
00663         // give special priority to font-xxx, color properties
00664         switch(prop->m_id)
00665         {
00666         case CSS_PROP_FONT_STYLE:
00667     case CSS_PROP_FONT_SIZE:
00668     case CSS_PROP_FONT_WEIGHT:
00669         case CSS_PROP_FONT_FAMILY:
00670         case CSS_PROP_FONT:
00671         case CSS_PROP_COLOR:
00672         case CSS_PROP_BACKGROUND_IMAGE:
00673         case CSS_PROP_DISPLAY:
00674             // these have to be applied first, because other properties use the computed
00675             // values of these properties.
00676         first = true;
00677             break;
00678         default:
00679             first = false;
00680             break;
00681         }
00682 
00683     array->prop = prop;
00684     array->pseudoId = RenderStyle::NOPSEUDO;
00685     array->selector = 0;
00686     array->position = i;
00687     array->priority = (!first << 30) | (source << 24);
00688     propsToApply[numProps++] = array++;
00689     }
00690     return numProps;
00691 }
00692 
00693 static bool subject;
00694 
00695 // modified version of the one in kurl.cpp
00696 static void cleanpath(QString &path)
00697 {
00698     int pos;
00699     while ( (pos = path.find( "/../" )) != -1 ) {
00700         int prev = 0;
00701         if ( pos > 0 )
00702             prev = path.findRev( "/", pos -1 );
00703         // don't remove the host, i.e. http://foo.org/../foo.html
00704         if (prev < 0 || (prev > 3 && path.findRev("://", prev-1) == prev-2))
00705             path.remove( pos, 3);
00706         else
00707             // matching directory found ?
00708             path.remove( prev, pos- prev + 3 );
00709     }
00710     pos = 0;
00711 
00712     // Don't remove "//" from an anchor identifier. -rjw
00713     // Set refPos to -2 to mean "I haven't looked for the anchor yet".
00714     // We don't want to waste a function call on the search for the anchor
00715     // in the vast majority of cases where there is no "//" in the path.
00716     int refPos = -2;
00717     while ( (pos = path.find( "//", pos )) != -1) {
00718         if (refPos == -2)
00719             refPos = path.find("#", 0);
00720         if (refPos > 0 && pos >= refPos)
00721             break;
00722 
00723         if ( pos == 0 || path[pos-1] != ':' )
00724             path.remove( pos, 1 );
00725         else
00726             pos += 2;
00727     }
00728     while ( (pos = path.find( "/./" )) != -1)
00729         path.remove( pos, 2 );
00730     //kdDebug() << "checkPseudoState " << path << endl;
00731 }
00732 
00733 static void checkPseudoState( const CSSStyleSelector::Encodedurl& encodedurl, DOM::ElementImpl *e )
00734 {
00735     if( e->id() != ID_A ) {
00736         pseudoState = PseudoNone;
00737         return;
00738     }
00739     DOMString attr = e->getAttribute(ATTR_HREF);
00740     if( attr.isNull() ) {
00741         pseudoState = PseudoNone;
00742         return;
00743     }
00744     QConstString cu(attr.unicode(), attr.length());
00745     QString u = cu.string();
00746     if ( !u.contains("://") ) {
00747         if ( u[0] == '/' )
00748             u = encodedurl.host + u;
00749         else if ( u[0] == '#' )
00750             u = encodedurl.file + u;
00751         else
00752             u = encodedurl.path + u;
00753         cleanpath( u );
00754     }
00755     //completeURL( attr.string() );
00756     bool contains = KHTMLFactory::vLinks()->contains( u );
00757     if ( !contains && u.contains('/')==2 )
00758       contains = KHTMLFactory::vLinks()->contains( u+'/' );
00759     pseudoState = contains ? PseudoVisited : PseudoLink;
00760 }
00761 
00762 void CSSStyleSelector::checkSelector(int selIndex, DOM::ElementImpl *e)
00763 {
00764     dynamicPseudo = RenderStyle::NOPSEUDO;
00765 
00766     NodeImpl *n = e;
00767 
00768     selectorCache[ selIndex ].state = Invalid;
00769     CSSSelector *sel = selectors[ selIndex ];
00770 
00771     // we have the subject part of the selector
00772     subject = true;
00773 
00774     // We track whether or not the rule contains only :hover and :active in a simple selector. If
00775     // so, we can't allow that to apply to every element on the page.  We assume the author intended
00776     // to apply the rules only to links.
00777     bool onlyHoverActive = (((sel->tag & NodeImpl_IdLocalMask) == NodeImpl_IdLocalMask) &&
00778                             (sel->match == CSSSelector::Pseudo &&
00779                               (sel->pseudoType() == CSSSelector::PseudoHover ||
00780                                sel->pseudoType() == CSSSelector::PseudoActive)));
00781     bool affectedByHover = style->affectedByHoverRules();
00782     bool affectedByActive = style->affectedByActiveRules();
00783 
00784     // first selector has to match
00785     if(!checkOneSelector(sel, e)) return;
00786 
00787     // check the subselectors
00788     CSSSelector::Relation relation = sel->relation;
00789     while((sel = sel->tagHistory))
00790     {
00791         if(!n->isElementNode()) return;
00792         switch(relation)
00793         {
00794         case CSSSelector::Descendant:
00795         {
00796             bool found = false;
00797             while(!found)
00798             {
00799         subject = false;
00800                 n = n->parentNode();
00801                 if(!n || !n->isElementNode()) return;
00802                 ElementImpl *elem = static_cast<ElementImpl *>(n);
00803                 if(checkOneSelector(sel, elem)) found = true;
00804             }
00805             break;
00806         }
00807         case CSSSelector::Child:
00808         {
00809         subject = false;
00810             n = n->parentNode();
00811             if (!strictParsing)
00812                 while (n && n->implicitNode()) n = n->parentNode();
00813             if(!n || !n->isElementNode()) return;
00814             ElementImpl *elem = static_cast<ElementImpl *>(n);
00815             if(!checkOneSelector(sel, elem)) return;
00816             break;
00817         }
00818         case CSSSelector::Sibling:
00819         {
00820             subject = false;
00821             n = n->previousSibling();
00822             while( n && !n->isElementNode() )
00823                 n = n->previousSibling();
00824             if( !n ) return;
00825             ElementImpl *elem = static_cast<ElementImpl *>(n);
00826             if(!checkOneSelector(sel, elem)) return;
00827             break;
00828         }
00829         case CSSSelector::Cousin:
00830         {
00831             subject = false;
00832             ElementImpl *elem = 0;
00833             do {
00834                 n = n->previousSibling();
00835                 while( n && !n->isElementNode() )
00836                     n = n->previousSibling();
00837                 if( !n ) return;
00838                 elem = static_cast<ElementImpl *>(n);
00839             } while (!checkOneSelector(sel, elem));
00840             break;
00841         }
00842         case CSSSelector::SubSelector:
00843     {
00844             if (onlyHoverActive)
00845                 onlyHoverActive = (sel->match == CSSSelector::Pseudo &&
00846                                    (sel->pseudoType() == CSSSelector::PseudoHover ||
00847                                     sel->pseudoType() == CSSSelector::PseudoActive));
00848 
00849         //kdDebug() << "CSSOrderedRule::checkSelector" << endl;
00850         ElementImpl *elem = static_cast<ElementImpl *>(n);
00851         // a selector is invalid if something follows :first-xxx
00852         if ( dynamicPseudo != RenderStyle::NOPSEUDO ) {
00853         return;
00854         }
00855         if(!checkOneSelector(sel, elem)) return;
00856         //kdDebug() << "CSSOrderedRule::checkSelector: passed" << endl;
00857         break;
00858     }
00859         }
00860         relation = sel->relation;
00861     }
00862 
00863     // disallow *:hover, *:active, and *:hover:active except for links
00864     if (onlyHoverActive && subject) {
00865         if (pseudoState == PseudoUnknown)
00866             checkPseudoState( encodedurl, e );
00867 
00868         if (pseudoState == PseudoNone) {
00869             if (!affectedByHover && style->affectedByHoverRules())
00870         style->setAffectedByHoverRules(false);
00871             if (!affectedByActive && style->affectedByActiveRules())
00872                 style->setAffectedByActiveRules(false);
00873         return;
00874     }
00875     }
00876 
00877     if ( dynamicPseudo != RenderStyle::NOPSEUDO ) {
00878     selectorCache[selIndex].state = AppliesPseudo;
00879     selectors[ selIndex ]->pseudoId = dynamicPseudo;
00880     } else
00881     selectorCache[ selIndex ].state = Applies;
00882     //qDebug( "selector %d applies", selIndex );
00883     //selectors[ selIndex ]->print();
00884     return;
00885 }
00886 
00887 bool CSSStyleSelector::checkOneSelector(DOM::CSSSelector *sel, DOM::ElementImpl *e)
00888 {
00889     if(!e)
00890         return false;
00891 
00892     unsigned int element_id = e->id();
00893     if ( (sel->tag & NodeImpl_IdNSMask) == NodeImpl_IdNSMask ) {
00894        // all namespaces would match
00895        unsigned int sel_id = sel->tag & NodeImpl_IdLocalMask;
00896        if ( (element_id & NodeImpl_IdLocalMask) != sel_id &&
00897             sel_id != NodeImpl_IdLocalMask )
00898            return false;
00899     } else {
00900        // specific namespace selected
00901        if( (element_id & NodeImpl_IdNSMask) != (sel->tag & NodeImpl_IdNSMask) )
00902            return false;
00903        if ( element_id != sel->tag &&
00904             (sel->tag & NodeImpl_IdLocalMask) != NodeImpl_IdLocalMask )
00905            return false;
00906     }
00907 
00908     if(sel->attr)
00909     {
00910        unsigned int attr_id = sel->attr;
00911        if ( (attr_id & NodeImpl_IdNSMask ) == NodeImpl_IdNSMask ) {
00912            // ### fixme: this should allow attributes from all
00913            // ### namespaces. I'm not 100% sure what the semantics
00914            // ### should be in this case. Do they all have to match?
00915            // ### Or should only one of them match. Anyways it might
00916            // ### be we have to iterate over all namespaces and check
00917            // ### all of them. For now we just set the namespace to
00918            // ### 0, so they at least match attributes in the default
00919            // ### namespace.
00920            attr_id &= NodeImpl_IdLocalMask;
00921        }
00922         DOMString value = e->getAttribute(attr_id);
00923         if(value.isNull()) return false; // attribute is not set
00924 
00925         switch(sel->match)
00926         {
00927         case CSSSelector::Exact:
00928             /* attribut values are case insensitive in all HTML modes,
00929                even in the strict ones */
00930             if ( e->getDocument()->htmlMode() != DocumentImpl::XHtml ) {
00931                 if ( strcasecmp(sel->value, value) )
00932                     return false;
00933             } else {
00934                 if ( strcmp(sel->value, value) )
00935                     return false;
00936             }
00937             break;
00938         case CSSSelector::Id:
00939         if( (strictParsing && strcmp(sel->value, value) ) ||
00940                 (!strictParsing && strcasecmp(sel->value, value)))
00941                 return false;
00942             break;
00943         case CSSSelector::Set:
00944             break;
00945         case CSSSelector::List:
00946         {
00947         int spacePos = value.find(' ', 0);
00948         if (spacePos == -1) {
00949         // There is no list, just a single item.  We can avoid
00950         // allocing QStrings and just treat this as an exact
00951         // match check.
00952         if( (strictParsing && strcmp(sel->value, value) ) ||
00953             (!strictParsing && strcasecmp(sel->value, value)))
00954             return false;
00955         break;
00956         }
00957 
00958             // The selector's value can't contain a space, or it's totally bogus.
00959             spacePos = sel->value.find(' ');
00960             if (spacePos != -1)
00961                 return false;
00962 
00963             QString str = value.string();
00964             QString selStr = sel->value.string();
00965             const int selStrlen = selStr.length();
00966             int pos = 0;
00967             for ( ;; ) {
00968                 pos = str.find(selStr, pos, strictParsing);
00969                 if ( pos == -1 ) return false;
00970                 if ( pos == 0 || str[pos-1] == ' ' ) {
00971                     uint endpos = pos + selStrlen;
00972                     if ( endpos >= str.length() || str[endpos] == ' ' )
00973                         break; // We have a match.
00974                 }
00975                 ++pos;
00976             }
00977             break;
00978         }
00979         case CSSSelector::Contain:
00980         {
00981             //kdDebug( 6080 ) << "checking for contains match" << endl;
00982             QString str = value.string();
00983             QString selStr = sel->value.string();
00984             int pos = str.find(selStr, 0, strictParsing);
00985             if(pos == -1) return false;
00986             break;
00987         }
00988         case CSSSelector::Begin:
00989         {
00990             //kdDebug( 6080 ) << "checking for beginswith match" << endl;
00991             QString str = value.string();
00992             QString selStr = sel->value.string();
00993             int pos = str.find(selStr, 0, strictParsing);
00994             if(pos != 0) return false;
00995             break;
00996         }
00997         case CSSSelector::End:
00998         {
00999             //kdDebug( 6080 ) << "checking for endswith match" << endl;
01000             QString str = value.string();
01001             QString selStr = sel->value.string();
01002         if (strictParsing && !str.endsWith(selStr)) return false;
01003         if (!strictParsing) {
01004             int pos = str.length() - selStr.length();
01005         if (pos < 0 || pos != str.find(selStr, pos, false) )
01006             return false;
01007         }
01008             break;
01009         }
01010         case CSSSelector::Hyphen:
01011         {
01012             //kdDebug( 6080 ) << "checking for hyphen match" << endl;
01013             QString str = value.string();
01014             QString selStr = sel->value.string();
01015             if(str.length() < selStr.length()) return false;
01016             // Check if str begins with selStr:
01017             if(str.find(selStr, 0, strictParsing) != 0) return false;
01018             // It does. Check for exact match or following '-':
01019             if(str.length() != selStr.length()
01020                 && str[selStr.length()] != '-') return false;
01021             break;
01022         }
01023         case CSSSelector::Pseudo:
01024         case CSSSelector::None:
01025             break;
01026         }
01027     }
01028     if(sel->match == CSSSelector::Pseudo)
01029     {
01030         // Pseudo elements. We need to check first child here. No dynamic pseudo
01031         // elements for the moment
01032 //  kdDebug() << "CSSOrderedRule::pseudo " << value << endl;
01033     switch (sel->pseudoType()) {
01034     case CSSSelector::PseudoEmpty:
01035         if (!e->firstChild())
01036         return true;
01037         break;
01038     case CSSSelector::PseudoFirstChild: {
01039         // first-child matches the first child that is an element!
01040             if (e->parentNode() && e->parentNode()->isElementNode()) {
01041                 DOM::NodeImpl* n = e->previousSibling();
01042                 while ( n && !n->isElementNode() )
01043                     n = n->previousSibling();
01044                 if ( !n )
01045                     return true;
01046             }
01047             break;
01048         }
01049         case CSSSelector::PseudoLastChild: {
01050             // last-child matches the last child that is an element!
01051             if (e->parentNode() && e->parentNode()->isElementNode()) {
01052                 DOM::NodeImpl* n = e->nextSibling();
01053                 while ( n && !n->isElementNode() )
01054                     n = n->nextSibling();
01055                 if ( !n )
01056                     return true;
01057             }
01058             break;
01059         }
01060         case CSSSelector::PseudoOnlyChild: {
01061             // If both first-child and last-child apply, then only-child applies.
01062             if (e->parentNode() && e->parentNode()->isElementNode()) {
01063                 DOM::NodeImpl* n = e->previousSibling();
01064                 while ( n && !n->isElementNode() )
01065                     n = n->previousSibling();
01066                 if ( !n ) {
01067                     n = e->nextSibling();
01068                     while ( n && !n->isElementNode() )
01069                         n = n->nextSibling();
01070                     if ( !n )
01071                         return true;
01072             }
01073             }
01074         break;
01075         }
01076     case CSSSelector::PseudoFirstLine:
01077         if ( subject ) {
01078         dynamicPseudo=RenderStyle::FIRST_LINE;
01079         return true;
01080         }
01081         break;
01082     case CSSSelector::PseudoFirstLetter:
01083         if ( subject ) {
01084         dynamicPseudo=RenderStyle::FIRST_LETTER;
01085         return true;
01086         }
01087         break;
01088         case CSSSelector::PseudoTarget:
01089 #ifdef APPLE_CHANGES
01090                 if (!e->getDocument()->getCSSTarget() && // :target matches the root when no CSS target exists
01091                      e == e->getDocument()->documentElement())
01092                     return true;
01093                 if (e == e->getDocument()->getCSSTarget())
01094                     return true;
01095 #endif
01096                 break;
01097     case CSSSelector::PseudoLink:
01098         if ( pseudoState == PseudoUnknown )
01099                     checkPseudoState( encodedurl, e );
01100         if ( pseudoState == PseudoLink )
01101         return true;
01102         break;
01103     case CSSSelector::PseudoVisited:
01104         if ( pseudoState == PseudoUnknown )
01105                     checkPseudoState( encodedurl, e );
01106         if ( pseudoState == PseudoVisited )
01107         return true;
01108         break;
01109         case CSSSelector::PseudoHover: {
01110         // If we're in quirks mode, then hover should never match anchors with no
01111         // href.  This is important for sites like wsj.com.
01112         if (strictParsing || e->id() != ID_A || e->hasAnchor()) {
01113         if (element == e)
01114             style->setAffectedByHoverRules(true);
01115         if (e->renderer()) {
01116             if (element != e)
01117             e->renderer()->style()->setAffectedByHoverRules(true);
01118             if (e->renderer()->mouseInside())
01119             return true;
01120         }
01121         }
01122         break;
01123             }
01124     case CSSSelector::PseudoFocus:
01125         if (e && e->focused()) {
01126         return true;
01127         }
01128         break;
01129     case CSSSelector::PseudoActive:
01130         // If we're in quirks mode, then :active should never match anchors with no
01131         // href.
01132         if (strictParsing || e->id() != ID_A || e->hasAnchor()) {
01133         if (element == e)
01134             style->setAffectedByActiveRules(true);
01135         else if (e->renderer())
01136             e->renderer()->style()->setAffectedByActiveRules(true);
01137         if (e->active())
01138             return true;
01139         }
01140         break;
01141         case CSSSelector::PseudoRoot:
01142             if (e == e->getDocument()->documentElement())
01143                 return true;
01144             break;
01145         case CSSSelector::PseudoNot: {
01146             // check the simple selector
01147             for (CSSSelector* subSel = sel->simpleSelector; subSel;
01148                  subSel = subSel->tagHistory) {
01149                 // :not cannot nest.  I don't really know why this is a restriction in CSS3,
01150                 // but it is, so let's honor it.
01151                 if (subSel->simpleSelector)
01152                     break;
01153                 if (!checkOneSelector(subSel, e))
01154                     return true;
01155             }
01156             break;
01157         }
01158     case CSSSelector::PseudoSelection:
01159         dynamicPseudo = RenderStyle::SELECTION;
01160         return true;
01161     case CSSSelector::PseudoBefore:
01162         dynamicPseudo = RenderStyle::BEFORE;
01163         return true;
01164     case CSSSelector::PseudoAfter:
01165         dynamicPseudo = RenderStyle::AFTER;
01166         return true;
01167 
01168     case CSSSelector::PseudoNotParsed:
01169         assert(false);
01170         break;
01171         case CSSSelector::PseudoLang:
01172         /* not supported for now */
01173     case CSSSelector::PseudoOther:
01174         break;
01175     }
01176     return false;
01177     }
01178     // ### add the rest of the checks...
01179     return true;
01180 }
01181 
01182 void CSSStyleSelector::clearLists()
01183 {
01184     delete [] selectors;
01185     if ( selectorCache ) {
01186         for ( unsigned int i = 0; i < selectors_size; i++ )
01187             delete [] selectorCache[i].props;
01188 
01189         delete [] selectorCache;
01190     }
01191     if ( properties ) {
01192     CSSOrderedProperty **prop = properties;
01193     while ( *prop ) {
01194         delete (*prop);
01195         prop++;
01196     }
01197         delete [] properties;
01198     }
01199     selectors = 0;
01200     properties = 0;
01201     selectorCache = 0;
01202 }
01203 
01204 
01205 void CSSStyleSelector::buildLists()
01206 {
01207     clearLists();
01208     // collect all selectors and Properties in lists. Then transfer them to the array for faster lookup.
01209 
01210     QPtrList<CSSSelector> selectorList;
01211     CSSOrderedPropertyList propertyList;
01212 
01213     if(m_medium == "print" && defaultPrintStyle)
01214       defaultPrintStyle->collect( &selectorList, &propertyList, Default,
01215         Default );
01216     else if(defaultStyle) defaultStyle->collect( &selectorList, &propertyList,
01217       Default, Default );
01218 
01219     if (!strictParsing && defaultQuirksStyle)
01220         defaultQuirksStyle->collect( &selectorList, &propertyList, Default, Default );
01221 
01222     if(userStyle) userStyle->collect(&selectorList, &propertyList, User, UserImportant );
01223     if(authorStyle) authorStyle->collect(&selectorList, &propertyList, Author, AuthorImportant );
01224 
01225     selectors_size = selectorList.count();
01226     selectors = new CSSSelector *[selectors_size];
01227     CSSSelector *s = selectorList.first();
01228     CSSSelector **sel = selectors;
01229     while ( s ) {
01230     *sel = s;
01231     s = selectorList.next();
01232     ++sel;
01233     }
01234 
01235     selectorCache = new SelectorCache[selectors_size];
01236     for ( unsigned int i = 0; i < selectors_size; i++ ) {
01237         selectorCache[i].state = Unknown;
01238         selectorCache[i].props_size = 0;
01239         selectorCache[i].props = 0;
01240     }
01241 
01242     // presort properties. Should make the sort() calls in styleForElement faster.
01243     propertyList.sort();
01244     properties_size = propertyList.count() + 1;
01245     properties = new CSSOrderedProperty *[ properties_size ];
01246     CSSOrderedProperty *p = propertyList.first();
01247     CSSOrderedProperty **prop = properties;
01248     while ( p ) {
01249     *prop = p;
01250     p = propertyList.next();
01251     ++prop;
01252     }
01253     *prop = 0;
01254 
01255     unsigned int* offsets = new unsigned int[selectors_size];
01256     if(properties[0])
01257     offsets[properties[0]->selector] = 0;
01258     for(unsigned int p = 1; p < properties_size; ++p) {
01259 
01260     if(!properties[p] || (properties[p]->selector != properties[p - 1]->selector)) {
01261         unsigned int sel = properties[p - 1]->selector;
01262             int* newprops = new int[selectorCache[sel].props_size+2];
01263             for ( unsigned int i=0; i < selectorCache[sel].props_size; i++ )
01264                 newprops[i] = selectorCache[sel].props[i];
01265 
01266         newprops[selectorCache[sel].props_size] = offsets[sel];
01267         newprops[selectorCache[sel].props_size+1] = p - offsets[sel];
01268             delete [] selectorCache[sel].props;
01269             selectorCache[sel].props = newprops;
01270             selectorCache[sel].props_size += 2;
01271 
01272         if(properties[p]) {
01273         sel = properties[p]->selector;
01274         offsets[sel] = p;
01275             }
01276         }
01277     }
01278     delete [] offsets;
01279 
01280 
01281 #if 0
01282     // and now the same for the selector map
01283     for ( unsigned int sel = 0; sel < selectors_size; ++sel ) {
01284         kdDebug( 6080 ) << "trying for sel: " << sel << endl;
01285         int len = 0;
01286         int offset = 0;
01287         bool matches = false;
01288         for ( unsigned int i = 0; i < selectors_size; i++ ) {
01289             int tag = selectors[i]->tag;
01290             if ( sel != tag && tag != -1 )
01291                 selectorCache[i].state = Invalid;
01292             else
01293                 selectorCache[i].state = Unknown;
01294 
01295             if ( matches != ( selectorCache[i].state == Unknown ) ) {
01296                 if ( matches ) {
01297                     kdDebug( 6080 ) << "new: offs: " << offset << " len: " << len << endl;
01298                     matches = false;
01299                 }
01300                 else {
01301                     matches = true;
01302 //                    offset = p-selectors;
01303                     len = 0;
01304                 }
01305             }
01306             ++len;
01307         }
01308     }
01309 #endif
01310 }
01311 
01312 
01313 // ----------------------------------------------------------------------
01314 
01315 
01316 CSSOrderedRule::CSSOrderedRule(DOM::CSSStyleRuleImpl *r, DOM::CSSSelector *s, int _index)
01317 {
01318     rule = r;
01319     if(rule) r->ref();
01320     index = _index;
01321     selector = s;
01322 }
01323 
01324 CSSOrderedRule::~CSSOrderedRule()
01325 {
01326     if(rule) rule->deref();
01327 }
01328 
01329 // -----------------------------------------------------------------
01330 
01331 CSSStyleSelectorList::CSSStyleSelectorList()
01332     : QPtrList<CSSOrderedRule>()
01333 {
01334     setAutoDelete(true);
01335 }
01336 CSSStyleSelectorList::~CSSStyleSelectorList()
01337 {
01338 }
01339 
01340 void CSSStyleSelectorList::append( CSSStyleSheetImpl *sheet,
01341                                    const DOMString &medium )
01342 {
01343     if(!sheet || !sheet->isCSSStyleSheet()) return;
01344 
01345     // No media implies "all", but if a medialist exists it must
01346     // contain our current medium
01347     if( sheet->media() && !sheet->media()->contains( medium ) )
01348         return; // style sheet not applicable for this medium
01349 
01350     int len = sheet->length();
01351 
01352     for(int i = 0; i< len; i++)
01353     {
01354         StyleBaseImpl *item = sheet->item(i);
01355         if(item->isStyleRule())
01356         {
01357             CSSStyleRuleImpl *r = static_cast<CSSStyleRuleImpl *>(item);
01358             QPtrList<CSSSelector> *s = r->selector();
01359             for(int j = 0; j < (int)s->count(); j++)
01360             {
01361                 CSSOrderedRule *rule = new CSSOrderedRule(r, s->at(j), count());
01362         QPtrList<CSSOrderedRule>::append(rule);
01363                 //kdDebug( 6080 ) << "appending StyleRule!" << endl;
01364             }
01365         }
01366         else if(item->isImportRule())
01367         {
01368             CSSImportRuleImpl *import = static_cast<CSSImportRuleImpl *>(item);
01369 
01370             //kdDebug( 6080 ) << "@import: Media: "
01371             //                << import->media()->mediaText().string() << endl;
01372 
01373             if( !import->media() || import->media()->contains( medium ) )
01374             {
01375                 CSSStyleSheetImpl *importedSheet = import->styleSheet();
01376                 append( importedSheet, medium );
01377             }
01378         }
01379         else if( item->isMediaRule() )
01380         {
01381             CSSMediaRuleImpl *r = static_cast<CSSMediaRuleImpl *>( item );
01382             CSSRuleListImpl *rules = r->cssRules();
01383 
01384             //DOMString mediaText = media->mediaText();
01385             //kdDebug( 6080 ) << "@media: Media: "
01386             //                << r->media()->mediaText().string() << endl;
01387 
01388             if( ( !r->media() || r->media()->contains( medium ) ) && rules)
01389             {
01390                 // Traverse child elements of the @import rule. Since
01391                 // many elements are not allowed as child we do not use
01392                 // a recursive call to append() here
01393                 for( unsigned j = 0; j < rules->length(); j++ )
01394                 {
01395                     //kdDebug( 6080 ) << "*** Rule #" << j << endl;
01396 
01397                     CSSRuleImpl *childItem = rules->item( j );
01398                     if( childItem->isStyleRule() )
01399                     {
01400                         // It is a StyleRule, so append it to our list
01401                         CSSStyleRuleImpl *styleRule =
01402                                 static_cast<CSSStyleRuleImpl *>( childItem );
01403 
01404                         QPtrList<CSSSelector> *s = styleRule->selector();
01405                         for( int j = 0; j < ( int ) s->count(); j++ )
01406                         {
01407                             CSSOrderedRule *orderedRule = new CSSOrderedRule(
01408                                             styleRule, s->at( j ), count() );
01409                         QPtrList<CSSOrderedRule>::append( orderedRule );
01410                         }
01411                     }
01412                     else
01413                     {
01414                         //kdDebug( 6080 ) << "Ignoring child rule of "
01415                         //    "ImportRule: rule is not a StyleRule!" << endl;
01416                     }
01417                 }   // for rules
01418             }   // if rules
01419             else
01420             {
01421                 //kdDebug( 6080 ) << "CSSMediaRule not rendered: "
01422                 //                << "rule empty or wrong medium!" << endl;
01423             }
01424         }
01425         // ### include other rules
01426     }
01427 }
01428 
01429 
01430 void CSSStyleSelectorList::collect( QPtrList<CSSSelector> *selectorList, CSSOrderedPropertyList *propList,
01431                     Source regular, Source important )
01432 {
01433     CSSOrderedRule *r = first();
01434     while( r ) {
01435     CSSSelector *sel = selectorList->first();
01436     int selectorNum = 0;
01437     while( sel ) {
01438         if ( *sel == *(r->selector) )
01439         break;
01440         sel = selectorList->next();
01441         selectorNum++;
01442     }
01443     if ( !sel )
01444         selectorList->append( r->selector );
01445 //  else
01446 //      qDebug("merged one selector");
01447     propList->append(r->rule->declaration(), selectorNum, r->selector->specificity(), regular, important );
01448     r = next();
01449     }
01450 }
01451 
01452 // -------------------------------------------------------------------------
01453 
01454 int CSSOrderedPropertyList::compareItems(QPtrCollection::Item i1, QPtrCollection::Item i2)
01455 {
01456     int diff =  static_cast<CSSOrderedProperty *>(i1)->priority
01457         - static_cast<CSSOrderedProperty *>(i2)->priority;
01458     return diff ? diff : static_cast<CSSOrderedProperty *>(i1)->position
01459         - static_cast<CSSOrderedProperty *>(i2)->position;
01460 }
01461 
01462 void CSSOrderedPropertyList::append(DOM::CSSStyleDeclarationImpl *decl, uint selector, uint specificity,
01463                     Source regular, Source important )
01464 {
01465     QPtrList<CSSProperty> *values = decl->values();
01466     if(!values) return;
01467     int len = values->count();
01468     for(int i = 0; i < len; i++)
01469     {
01470         CSSProperty *prop = values->at(i);
01471     Source source = regular;
01472 
01473     if( prop->m_bImportant ) source = important;
01474     if( prop->nonCSSHint ) source = NonCSSHint;
01475 
01476     bool first = false;
01477         // give special priority to font-xxx, color properties
01478         switch(prop->m_id)
01479         {
01480         case CSS_PROP_FONT_STYLE:
01481     case CSS_PROP_FONT_SIZE:
01482     case CSS_PROP_FONT_WEIGHT:
01483         case CSS_PROP_FONT_FAMILY:
01484         case CSS_PROP_FONT:
01485         case CSS_PROP_COLOR:
01486         case CSS_PROP_BACKGROUND_IMAGE:
01487         case CSS_PROP_DISPLAY:
01488             // these have to be applied first, because other properties use the computed
01489             // values of these porperties.
01490         first = true;
01491             break;
01492         default:
01493             break;
01494         }
01495 
01496     QPtrList<CSSOrderedProperty>::append(new CSSOrderedProperty(prop, selector,
01497                                  first, source, specificity,
01498                                  count() ));
01499     }
01500 }
01501 
01502 // -------------------------------------------------------------------------------------
01503 // this is mostly boring stuff on how to apply a certain rule to the renderstyle...
01504 
01505 static Length convertToLength( CSSPrimitiveValueImpl *primitiveValue, RenderStyle *style, QPaintDeviceMetrics *paintDeviceMetrics, bool *ok = 0 )
01506 {
01507     Length l;
01508     if ( !primitiveValue ) {
01509     if ( ok )
01510             *ok = false;
01511     } else {
01512     int type = primitiveValue->primitiveType();
01513     if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
01514         l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
01515     else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
01516         l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE)), Percent);
01517     else if(type == CSSPrimitiveValue::CSS_NUMBER)
01518         l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)*100), Percent);
01519     else if (type == CSSPrimitiveValue::CSS_HTML_RELATIVE)
01520         l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_HTML_RELATIVE)), Relative);
01521     else if ( ok )
01522         *ok = false;
01523     }
01524     return l;
01525 }
01526 
01527 
01528 // color mapping code
01529 struct colorMap {
01530     int css_value;
01531     QRgb color;
01532 };
01533 
01534 static const colorMap cmap[] = {
01535     { CSS_VAL_AQUA, 0xFF00FFFF },
01536     { CSS_VAL_BLACK, 0xFF000000 },
01537     { CSS_VAL_BLUE, 0xFF0000FF },
01538     { CSS_VAL_CRIMSON, 0xFFDC143C },
01539     { CSS_VAL_FUCHSIA, 0xFFFF00FF },
01540     { CSS_VAL_GRAY, 0xFF808080 },
01541     { CSS_VAL_GREEN, 0xFF008000  },
01542     { CSS_VAL_INDIGO, 0xFF4B0082 },
01543     { CSS_VAL_LIME, 0xFF00FF00 },
01544     { CSS_VAL_MAROON, 0xFF800000 },
01545     { CSS_VAL_NAVY, 0xFF000080 },
01546     { CSS_VAL_OLIVE, 0xFF808000  },
01547     { CSS_VAL_ORANGE, 0xFFFFA500 },
01548     { CSS_VAL_PURPLE, 0xFF800080 },
01549     { CSS_VAL_RED, 0xFFFF0000 },
01550     { CSS_VAL_SILVER, 0xFFC0C0C0 },
01551     { CSS_VAL_TEAL, 0xFF008080  },
01552     { CSS_VAL_WHITE, 0xFFFFFFFF },
01553     { CSS_VAL_YELLOW, 0xFFFFFF00 },
01554     { CSS_VAL_INVERT, invertedColor },
01555     { CSS_VAL_TRANSPARENT, transparentColor },
01556     { CSS_VAL_GREY, 0xff808080 },
01557     { 0, 0 }
01558 };
01559 
01560 struct uiColors {
01561     int css_value;
01562     const char * configGroup;
01563     const char * configEntry;
01564 QPalette::ColorGroup group;
01565 QColorGroup::ColorRole role;
01566 };
01567 
01568 const char * const wmgroup = "WM";
01569 const char * const generalgroup = "General";
01570 
01571 /* Mapping system settings to CSS 2
01572 * Tried hard to get an appropriate mapping - schlpbch
01573 */
01574 static const uiColors uimap[] = {
01575     // Active window border.
01576     { CSS_VAL_ACTIVEBORDER, wmgroup, "background", QPalette::Active, QColorGroup::Light },
01577     // Active window caption.
01578     { CSS_VAL_ACTIVECAPTION, wmgroup, "background", QPalette::Active, QColorGroup::Text },
01579         // Text in caption, size box, and scrollbar arrow box.
01580     { CSS_VAL_CAPTIONTEXT, wmgroup, "activeForeground", QPalette::Active, QColorGroup::Text },
01581     // Face color for three-dimensional display elements.
01582     { CSS_VAL_BUTTONFACE, wmgroup, 0, QPalette::Inactive, QColorGroup::Button },
01583     // Dark shadow for three-dimensional display elements (for edges facing away from the light source).
01584     { CSS_VAL_BUTTONHIGHLIGHT, wmgroup, 0, QPalette::Inactive, QColorGroup::Light },
01585     // Shadow color for three-dimensional display elements.
01586     { CSS_VAL_BUTTONSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Shadow },
01587     // Text on push buttons.
01588     { CSS_VAL_BUTTONTEXT, wmgroup, "buttonForeground", QPalette::Inactive, QColorGroup::ButtonText },
01589     // Dark shadow for three-dimensional display elements.
01590     { CSS_VAL_THREEDDARKSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Dark },
01591     // Face color for three-dimensional display elements.
01592     { CSS_VAL_THREEDFACE, wmgroup, 0, QPalette::Inactive, QColorGroup::Button },
01593     // Highlight color for three-dimensional display elements.
01594     { CSS_VAL_THREEDHIGHLIGHT, wmgroup, 0, QPalette::Inactive, QColorGroup::Light },
01595     // Light color for three-dimensional display elements (for edges facing the light source).
01596     { CSS_VAL_THREEDLIGHTSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Midlight },
01597     // Dark shadow for three-dimensional display elements.
01598     { CSS_VAL_THREEDSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Shadow },
01599 
01600     // Inactive window border.
01601     { CSS_VAL_INACTIVEBORDER, wmgroup, "background", QPalette::Disabled, QColorGroup::Background },
01602     // Inactive window caption.
01603     { CSS_VAL_INACTIVECAPTION, wmgroup, "inactiveBackground", QPalette::Disabled, QColorGroup::Background },
01604     // Color of text in an inactive caption.
01605     { CSS_VAL_INACTIVECAPTIONTEXT, wmgroup, "inactiveForeground", QPalette::Disabled, QColorGroup::Text },
01606     { CSS_VAL_GRAYTEXT, wmgroup, 0, QPalette::Disabled, QColorGroup::Text },
01607 
01608     // Menu background
01609     { CSS_VAL_MENU, generalgroup, "background", QPalette::Inactive, QColorGroup::Background },
01610     // Text in menus
01611     { CSS_VAL_MENUTEXT, generalgroup, "foreground", QPalette::Inactive, QColorGroup::Background },
01612 
01613         // Text of item(s) selected in a control.
01614     { CSS_VAL_HIGHLIGHT, generalgroup, "selectBackground", QPalette::Inactive, QColorGroup::Background },
01615 
01616     // Text of item(s) selected in a control.
01617     { CSS_VAL_HIGHLIGHTTEXT, generalgroup, "selectForeground", QPalette::Inactive, QColorGroup::Background },
01618 
01619     // Background color of multiple document interface.
01620     { CSS_VAL_APPWORKSPACE, generalgroup, "background", QPalette::Inactive, QColorGroup::Text },
01621 
01622     // Scroll bar gray area.
01623     { CSS_VAL_SCROLLBAR, generalgroup, "background", QPalette::Inactive, QColorGroup::Background },
01624 
01625     // Window background.
01626     { CSS_VAL_WINDOW, generalgroup, "windowBackground", QPalette::Inactive, QColorGroup::Background },
01627     // Window frame.
01628     { CSS_VAL_WINDOWFRAME, generalgroup, "windowBackground", QPalette::Inactive, QColorGroup::Background },
01629         // WindowText
01630     { CSS_VAL_WINDOWTEXT, generalgroup, "windowForeground", QPalette::Inactive, QColorGroup::Text },
01631     { CSS_VAL_TEXT, generalgroup, 0, QPalette::Inactive, QColorGroup::Text },
01632     { 0, 0, 0, QPalette::NColorGroups, QColorGroup::NColorRoles }
01633 };
01634 
01635 static QColor colorForCSSValue( int css_value )
01636 {
01637     // try the regular ones first
01638     const colorMap *col = cmap;
01639     while ( col->css_value && col->css_value != css_value )
01640     ++col;
01641     if ( col->css_value )
01642     return col->color;
01643 
01644     const uiColors *uicol = uimap;
01645     while ( uicol->css_value && uicol->css_value != css_value )
01646     ++uicol;
01647 #ifndef APPLE_CHANGES
01648     if ( !uicol->css_value ) {
01649     if ( css_value == CSS_VAL_INFOBACKGROUND )
01650         return QToolTip::palette().inactive().background();
01651     else if ( css_value == CSS_VAL_INFOTEXT )
01652         return QToolTip::palette().inactive().foreground();
01653     else if ( css_value == CSS_VAL_BACKGROUND ) {
01654         KConfig bckgrConfig("kdesktoprc", true, false); // No multi-screen support
01655         bckgrConfig.setGroup("Desktop0");
01656         // Desktop background.
01657         return bckgrConfig.readColorEntry("Color1", &qApp->palette().disabled().background());
01658     }
01659     return QColor();
01660     }
01661 #endif
01662 
01663     const QPalette &pal = qApp->palette();
01664     QColor c = pal.color( uicol->group, uicol->role );
01665 #ifndef APPLE_CHANGES
01666     if ( uicol->configEntry ) {
01667     KConfig *globalConfig = KGlobal::config();
01668     globalConfig->setGroup( uicol->configGroup );
01669     c = globalConfig->readColorEntry( uicol->configEntry, &c );
01670     }
01671 #endif
01672 
01673     return c;
01674 }
01675 
01676 
01677 void CSSStyleSelector::applyRule( int id, DOM::CSSValueImpl *value )
01678 {
01679 //      kdDebug( 6080 ) << "applying property " << id << endl;
01680 
01681     CSSPrimitiveValueImpl *primitiveValue = 0;
01682     if(value->isPrimitiveValue()) primitiveValue = static_cast<CSSPrimitiveValueImpl *>(value);
01683 
01684     Length l;
01685     bool apply = false;
01686 
01687     bool isInherit = (parentNode && value->cssValueType() == CSSValue::CSS_INHERIT);
01688     bool isInitial = (value->cssValueType() == CSSValue::CSS_INITIAL) ||
01689                      (!parentNode && value->cssValueType() == CSSValue::CSS_INHERIT);
01690 
01691     // What follows is a list that maps the CSS properties into their corresponding front-end
01692     // RenderStyle values.  Shorthands (e.g. border, background) occur in this list as well and
01693     // are only hit when mapping "inherit" or "initial" into front-end values.
01694     switch(id)
01695     {
01696 // ident only properties
01697     case CSS_PROP_BACKGROUND_ATTACHMENT:
01698         HANDLE_INHERIT_AND_INITIAL(backgroundAttachment, BackgroundAttachment)
01699         if(!primitiveValue) break;
01700         switch(primitiveValue->getIdent())
01701         {
01702         case CSS_VAL_FIXED:
01703             {
01704                 style->setBackgroundAttachment(false);
01705         // only use slow repaints if we actually have a background pixmap
01706                 if( style->backgroundImage() )
01707                     view->useSlowRepaints();
01708                 break;
01709             }
01710         case CSS_VAL_SCROLL:
01711             style->setBackgroundAttachment(true);
01712             break;
01713         default:
01714             return;
01715         }
01716     case CSS_PROP_BACKGROUND_REPEAT:
01717     {
01718         HANDLE_INHERIT_AND_INITIAL(backgroundRepeat, BackgroundRepeat)
01719         if(!primitiveValue) return;
01720     switch(primitiveValue->getIdent())
01721     {
01722     case CSS_VAL_REPEAT:
01723         style->setBackgroundRepeat( REPEAT );
01724         break;
01725     case CSS_VAL_REPEAT_X:
01726         style->setBackgroundRepeat( REPEAT_X );
01727         break;
01728     case CSS_VAL_REPEAT_Y:
01729         style->setBackgroundRepeat( REPEAT_Y );
01730         break;
01731     case CSS_VAL_NO_REPEAT:
01732         style->setBackgroundRepeat( NO_REPEAT );
01733         break;
01734     default:
01735         return;
01736     }
01737     }
01738     case CSS_PROP_BORDER_COLLAPSE:
01739         HANDLE_INHERIT_AND_INITIAL(borderCollapse, BorderCollapse)
01740         if(!primitiveValue) break;
01741         switch(primitiveValue->getIdent())
01742         {
01743         case CSS_VAL_COLLAPSE:
01744             style->setBorderCollapse(true);
01745             break;
01746         case CSS_VAL_SEPARATE:
01747             style->setBorderCollapse(false);
01748             break;
01749         default:
01750             return;
01751         }
01752         break;
01753 
01754     case CSS_PROP_BORDER_TOP_STYLE:
01755         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderTopStyle, BorderTopStyle, BorderStyle)
01756         if (!primitiveValue) return;
01757         style->setBorderTopStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
01758         break;
01759     case CSS_PROP_BORDER_RIGHT_STYLE:
01760         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderRightStyle, BorderRightStyle, BorderStyle)
01761         if (!primitiveValue) return;
01762         style->setBorderRightStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
01763         break;
01764     case CSS_PROP_BORDER_BOTTOM_STYLE:
01765         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderBottomStyle, BorderBottomStyle, BorderStyle)
01766         if (!primitiveValue) return;
01767         style->setBorderBottomStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
01768         break;
01769     case CSS_PROP_BORDER_LEFT_STYLE:
01770         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderLeftStyle, BorderLeftStyle, BorderStyle)
01771         if (!primitiveValue) return;
01772         style->setBorderLeftStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
01773         break;
01774     case CSS_PROP_OUTLINE_STYLE:
01775         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(outlineStyle, OutlineStyle, BorderStyle)
01776         if (!primitiveValue) return;
01777         style->setOutlineStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
01778         break;
01779     case CSS_PROP_CAPTION_SIDE:
01780     {
01781         HANDLE_INHERIT_AND_INITIAL(captionSide, CaptionSide)
01782         if(!primitiveValue) break;
01783         ECaptionSide c = RenderStyle::initialCaptionSide();
01784         switch(primitiveValue->getIdent())
01785         {
01786         case CSS_VAL_LEFT:
01787             c = CAPLEFT; break;
01788         case CSS_VAL_RIGHT:
01789             c = CAPRIGHT; break;
01790         case CSS_VAL_TOP:
01791             c = CAPTOP; break;
01792         case CSS_VAL_BOTTOM:
01793             c = CAPBOTTOM; break;
01794         default:
01795             return;
01796         }
01797         style->setCaptionSide(c);
01798         return;
01799     }
01800     case CSS_PROP_CLEAR:
01801     {
01802         HANDLE_INHERIT_AND_INITIAL(clear, Clear)
01803         if(!primitiveValue) break;
01804         EClear c = CNONE;
01805         switch(primitiveValue->getIdent())
01806         {
01807         case CSS_VAL_LEFT:
01808             c = CLEFT; break;
01809         case CSS_VAL_RIGHT:
01810             c = CRIGHT; break;
01811         case CSS_VAL_BOTH:
01812             c = CBOTH; break;
01813         case CSS_VAL_NONE:
01814             c = CNONE; break;
01815         default:
01816             return;
01817         }
01818         style->setClear(c);
01819         return;
01820     }
01821     case CSS_PROP_DIRECTION:
01822     {
01823         HANDLE_INHERIT_AND_INITIAL(direction, Direction)
01824         if(!primitiveValue) break;
01825         style->setDirection( (EDirection) (primitiveValue->getIdent() - CSS_VAL_LTR) );
01826         return;
01827     }
01828     case CSS_PROP_DISPLAY:
01829     {
01830         HANDLE_INHERIT_AND_INITIAL(display, Display)
01831         if(!primitiveValue) break;
01832     int id = primitiveValue->getIdent();
01833         style->setDisplay( id == CSS_VAL_NONE ? NONE : EDisplay(id - CSS_VAL_INLINE) );
01834         break;
01835     }
01836 
01837     case CSS_PROP_EMPTY_CELLS:
01838     {
01839         HANDLE_INHERIT(emptyCells, EmptyCells);
01840         if (!primitiveValue) break;
01841         int id = primitiveValue->getIdent();
01842         if (id == CSS_VAL_SHOW)
01843             style->setEmptyCells(SHOW);
01844         else if (id == CSS_VAL_HIDE)
01845             style->setEmptyCells(HIDE);
01846         break;
01847     }
01848     case CSS_PROP_FLOAT:
01849     {
01850         HANDLE_INHERIT_AND_INITIAL(floating, Floating)
01851         if(!primitiveValue) return;
01852         EFloat f;
01853         switch(primitiveValue->getIdent())
01854         {
01855         case CSS_VAL_LEFT:
01856             f = FLEFT; break;
01857         case CSS_VAL_RIGHT:
01858             f = FRIGHT; break;
01859         case CSS_VAL_NONE:
01860         case CSS_VAL_CENTER:  //Non standart CSS-Value
01861             f = FNONE; break;
01862         default:
01863             return;
01864         }
01865         if (f!=FNONE && style->display()==LIST_ITEM)
01866             style->setDisplay(BLOCK);
01867 
01868         style->setFloating(f);
01869         break;
01870     }
01871 
01872     case CSS_PROP_FONT_STYLE:
01873     {
01874         FontDef fontDef = style->htmlFont().fontDef;
01875         if (isInherit)
01876             fontDef.italic = parentStyle->htmlFont().fontDef.italic;
01877     else if (isInitial)
01878             fontDef.italic = false;
01879         else {
01880         if(!primitiveValue) return;
01881         switch(primitiveValue->getIdent()) {
01882         case CSS_VAL_OBLIQUE:
01883         // ### oblique is the same as italic for the moment...
01884         case CSS_VAL_ITALIC:
01885             fontDef.italic = true;
01886             break;
01887         case CSS_VAL_NORMAL:
01888             fontDef.italic = false;
01889             break;
01890         default:
01891             return;
01892         }
01893     }
01894         fontDirty |= style->setFontDef( fontDef );
01895         break;
01896     }
01897 
01898 
01899     case CSS_PROP_FONT_VARIANT:
01900     {
01901         FontDef fontDef = style->htmlFont().fontDef;
01902         if (isInherit)
01903             fontDef.smallCaps = parentStyle->htmlFont().fontDef.weight;
01904         else if (isInitial)
01905             fontDef.smallCaps = false;
01906         else {
01907         if(!primitiveValue) return;
01908         int id = primitiveValue->getIdent();
01909         if ( id == CSS_VAL_NORMAL )
01910         fontDef.smallCaps = false;
01911         else if ( id == CSS_VAL_SMALL_CAPS )
01912         fontDef.smallCaps = true;
01913         else
01914         return;
01915     }
01916     fontDirty |= style->setFontDef( fontDef );
01917     break;
01918     }
01919 
01920     case CSS_PROP_FONT_WEIGHT:
01921     {
01922         FontDef fontDef = style->htmlFont().fontDef;
01923         if (isInherit)
01924             fontDef.weight = parentStyle->htmlFont().fontDef.weight;
01925         else if (isInitial)
01926             fontDef.weight = QFont::Normal;
01927         else {
01928         if(!primitiveValue) return;
01929         if(primitiveValue->getIdent())
01930         {
01931         switch(primitiveValue->getIdent()) {
01932             // ### we just support normal and bold fonts at the moment...
01933             // setWeight can actually accept values between 0 and 99...
01934         case CSS_VAL_BOLD:
01935         case CSS_VAL_BOLDER:
01936         case CSS_VAL_600:
01937         case CSS_VAL_700:
01938         case CSS_VAL_800:
01939         case CSS_VAL_900:
01940             fontDef.weight = QFont::Bold;
01941             break;
01942         case CSS_VAL_NORMAL:
01943         case CSS_VAL_LIGHTER:
01944         case CSS_VAL_100:
01945         case CSS_VAL_200:
01946         case CSS_VAL_300:
01947         case CSS_VAL_400:
01948         case CSS_VAL_500:
01949             fontDef.weight = QFont::Normal;
01950             break;
01951         default:
01952             return;
01953         }
01954         }
01955         else
01956         {
01957         // ### fix parsing of 100-900 values in parser, apply them here
01958         }
01959     }
01960         fontDirty |= style->setFontDef( fontDef );
01961         break;
01962     }
01963 
01964     case CSS_PROP_LIST_STYLE_POSITION:
01965     {
01966         HANDLE_INHERIT_AND_INITIAL(listStylePosition, ListStylePosition)
01967         if (!primitiveValue) return;
01968         if (primitiveValue->getIdent())
01969             style->setListStylePosition( (EListStylePosition) (primitiveValue->getIdent() - CSS_VAL_OUTSIDE) );
01970         return;
01971     }
01972 
01973     case CSS_PROP_LIST_STYLE_TYPE:
01974     {
01975         HANDLE_INHERIT_AND_INITIAL(listStyleType, ListStyleType)
01976         if (!primitiveValue) return;
01977         if (primitiveValue->getIdent())
01978         {
01979             EListStyleType t;
01980         int id = primitiveValue->getIdent();
01981         if ( id == CSS_VAL_NONE) { // important!!
01982           t = LNONE;
01983         } else {
01984           t = EListStyleType(id - CSS_VAL_DISC);
01985         }
01986             style->setListStyleType(t);
01987         }
01988         return;
01989     }
01990 
01991     case CSS_PROP_OVERFLOW:
01992     {
01993         HANDLE_INHERIT_AND_INITIAL(overflow, Overflow)
01994         if (!primitiveValue) return;
01995         EOverflow o;
01996         switch(primitiveValue->getIdent())
01997         {
01998         case CSS_VAL_VISIBLE:
01999             o = OVISIBLE; break;
02000         case CSS_VAL_HIDDEN:
02001             o = OHIDDEN; break;
02002         case CSS_VAL_SCROLL:
02003         o = OSCROLL; break;
02004         case CSS_VAL_AUTO:
02005         o = OAUTO; break;
02006         case CSS_VAL_MARQUEE:
02007             o = OMARQUEE; break;
02008         default:
02009             return;
02010         }
02011         style->setOverflow(o);
02012         return;
02013     }
02014     break;
02015     case CSS_PROP_PAGE_BREAK_BEFORE:
02016     {
02017         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakBefore, PageBreakBefore, PageBreak)
02018         if (!primitiveValue) return;
02019         switch (primitiveValue->getIdent()) {
02020             case CSS_VAL_AUTO:
02021                 style->setPageBreakBefore(PBAUTO);
02022                 break;
02023             case CSS_VAL_LEFT:
02024             case CSS_VAL_RIGHT:
02025             case CSS_VAL_ALWAYS:
02026                 style->setPageBreakBefore(PBALWAYS); // CSS2.1: "Conforming user agents may map left/right to always."
02027                 break;
02028             case CSS_VAL_AVOID:
02029                 style->setPageBreakBefore(PBAVOID);
02030                 break;
02031         }
02032         break;
02033     }
02034 
02035     case CSS_PROP_PAGE_BREAK_AFTER:
02036     {
02037         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakAfter, PageBreakAfter, PageBreak)
02038         if (!primitiveValue) return;
02039         switch (primitiveValue->getIdent()) {
02040             case CSS_VAL_AUTO:
02041                 style->setPageBreakAfter(PBAUTO);
02042                 break;
02043             case CSS_VAL_LEFT:
02044             case CSS_VAL_RIGHT:
02045             case CSS_VAL_ALWAYS:
02046                 style->setPageBreakAfter(PBALWAYS); // CSS2.1: "Conforming user agents may map left/right to always."
02047                 break;
02048             case CSS_VAL_AVOID:
02049                 style->setPageBreakAfter(PBAVOID);
02050                 break;
02051         }
02052         break;
02053     }
02054 
02055     case CSS_PROP_PAGE_BREAK_INSIDE: {
02056         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakInside, PageBreakInside, PageBreak)
02057         if (!primitiveValue) return;
02058         if (primitiveValue->getIdent() == CSS_VAL_AUTO)
02059             style->setPageBreakInside(PBAUTO);
02060         else if (primitiveValue->getIdent() == CSS_VAL_AVOID)
02061             style->setPageBreakInside(PBAVOID);
02062         return;
02063     }
02064 //    case CSS_PROP_PAUSE_AFTER:
02065 //    case CSS_PROP_PAUSE_BEFORE:
02066         break;
02067 
02068     case CSS_PROP_POSITION:
02069     {
02070         HANDLE_INHERIT_AND_INITIAL(position, Position)
02071         if (!primitiveValue) return;
02072         EPosition p;
02073         switch(primitiveValue->getIdent())
02074         {
02075         case CSS_VAL_STATIC:
02076             p = STATIC; break;
02077         case CSS_VAL_RELATIVE:
02078             p = RELATIVE; break;
02079         case CSS_VAL_ABSOLUTE:
02080             p = ABSOLUTE; break;
02081         case CSS_VAL_FIXED:
02082             {
02083                 view->useSlowRepaints();
02084                 p = FIXED;
02085                 break;
02086             }
02087         default:
02088             return;
02089         }
02090         style->setPosition(p);
02091         return;
02092     }
02093 
02094     case CSS_PROP_TABLE_LAYOUT: {
02095         HANDLE_INHERIT_AND_INITIAL(tableLayout, TableLayout)
02096 
02097     if ( !primitiveValue )
02098         return;
02099 
02100     ETableLayout l = RenderStyle::initialTableLayout();
02101     switch( primitiveValue->getIdent() ) {
02102     case CSS_VAL_FIXED:
02103         l = TFIXED;
02104         // fall through
02105     case CSS_VAL_AUTO:
02106         style->setTableLayout( l );
02107     default:
02108         break;
02109     }
02110     break;
02111     }
02112 
02113     case CSS_PROP_UNICODE_BIDI: {
02114         HANDLE_INHERIT_AND_INITIAL(unicodeBidi, UnicodeBidi)
02115         if(!primitiveValue) break;
02116         switch (primitiveValue->getIdent()) {
02117             case CSS_VAL_NORMAL:
02118                 style->setUnicodeBidi(UBNormal);
02119                 break;
02120             case CSS_VAL_EMBED:
02121                 style->setUnicodeBidi(Embed);
02122                 break;
02123             case CSS_VAL_BIDI_OVERRIDE:
02124                 style->setUnicodeBidi(Override);
02125                 break;
02126             default:
02127                 return;
02128         }
02129     break;
02130     }
02131     case CSS_PROP_TEXT_TRANSFORM: {
02132         HANDLE_INHERIT_AND_INITIAL(textTransform, TextTransform)
02133 
02134         if(!primitiveValue) break;
02135         if(!primitiveValue->getIdent()) return;
02136 
02137         ETextTransform tt;
02138         switch(primitiveValue->getIdent()) {
02139         case CSS_VAL_CAPITALIZE:  tt = CAPITALIZE;  break;
02140         case CSS_VAL_UPPERCASE:   tt = UPPERCASE;   break;
02141         case CSS_VAL_LOWERCASE:   tt = LOWERCASE;   break;
02142         case CSS_VAL_NONE:
02143         default:                  tt = TTNONE;      break;
02144         }
02145         style->setTextTransform(tt);
02146         break;
02147         }
02148 
02149     case CSS_PROP_VISIBILITY:
02150     {
02151         HANDLE_INHERIT_AND_INITIAL(visibility, Visibility)
02152 
02153         if(!primitiveValue) break;
02154         switch( primitiveValue->getIdent() ) {
02155         case CSS_VAL_HIDDEN:
02156             style->setVisibility( HIDDEN );
02157             break;
02158         case CSS_VAL_VISIBLE:
02159             style->setVisibility( VISIBLE );
02160             break;
02161         case CSS_VAL_COLLAPSE:
02162             style->setVisibility( COLLAPSE );
02163         default:
02164             break;
02165         }
02166         break;
02167     }
02168     case CSS_PROP_WHITE_SPACE:
02169         HANDLE_INHERIT_AND_INITIAL(whiteSpace, WhiteSpace)
02170 
02171         if(!primitiveValue) break;
02172         if(!primitiveValue->getIdent()) return;
02173 
02174         EWhiteSpace s;
02175         switch(primitiveValue->getIdent()) {
02176         case CSS_VAL__KHTML_NOWRAP:
02177             s = KHTML_NOWRAP;
02178             break;
02179         case CSS_VAL_NOWRAP:
02180             s = NOWRAP;
02181             break;
02182         case CSS_VAL_PRE:
02183             s = PRE;
02184             break;
02185         case CSS_VAL_NORMAL:
02186         default:
02187             s = NORMAL;
02188             break;
02189         }
02190         style->setWhiteSpace(s);
02191         break;
02192 
02193     case CSS_PROP_BACKGROUND_POSITION:
02194         if (isInherit) {
02195             style->setBackgroundXPosition(parentStyle->backgroundXPosition());
02196             style->setBackgroundYPosition(parentStyle->backgroundYPosition());
02197         }
02198         else if (isInitial) {
02199             style->setBackgroundXPosition(RenderStyle::initialBackgroundXPosition());
02200             style->setBackgroundYPosition(RenderStyle::initialBackgroundYPosition());
02201         }
02202         break;
02203     case CSS_PROP_BACKGROUND_POSITION_X: {
02204         HANDLE_INHERIT_AND_INITIAL(backgroundXPosition, BackgroundXPosition)
02205         if(!primitiveValue) break;
02206         Length l;
02207         int type = primitiveValue->primitiveType();
02208         if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02209             l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02210         else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02211             l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02212         else
02213             return;
02214         style->setBackgroundXPosition(l);
02215         break;
02216     }
02217     case CSS_PROP_BACKGROUND_POSITION_Y: {
02218         HANDLE_INHERIT_AND_INITIAL(backgroundYPosition, BackgroundYPosition)
02219         if(!primitiveValue) break;
02220         Length l;
02221         int type = primitiveValue->primitiveType();
02222         if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02223             l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02224         else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02225             l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02226         else
02227             return;
02228         style->setBackgroundYPosition(l);
02229         break;
02230     }
02231     case CSS_PROP_BORDER_SPACING: {
02232         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02233         style->setBorderHorizontalSpacing(parentStyle->borderHorizontalSpacing());
02234         style->setBorderVerticalSpacing(parentStyle->borderVerticalSpacing());
02235         break;
02236     }
02237     case CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING: {
02238         HANDLE_INHERIT_AND_INITIAL(borderHorizontalSpacing, BorderHorizontalSpacing)
02239         if (!primitiveValue) break;
02240         short spacing =  primitiveValue->computeLength(style, paintDeviceMetrics);
02241         style->setBorderHorizontalSpacing(spacing);
02242         break;
02243     }
02244     case CSS_PROP__KHTML_BORDER_VERTICAL_SPACING: {
02245         HANDLE_INHERIT_AND_INITIAL(borderVerticalSpacing, BorderVerticalSpacing)
02246         if (!primitiveValue) break;
02247         short spacing =  primitiveValue->computeLength(style, paintDeviceMetrics);
02248         style->setBorderVerticalSpacing(spacing);
02249         break;
02250     }
02251 
02252     case CSS_PROP_CURSOR:
02253         HANDLE_INHERIT_AND_INITIAL(cursor, Cursor)
02254         if(primitiveValue)
02255         style->setCursor( (ECursor) (primitiveValue->getIdent() - CSS_VAL_AUTO) );
02256         break;
02257 // colors || inherit
02258     case CSS_PROP_BACKGROUND_COLOR:
02259     case CSS_PROP_BORDER_TOP_COLOR:
02260     case CSS_PROP_BORDER_RIGHT_COLOR:
02261     case CSS_PROP_BORDER_BOTTOM_COLOR:
02262     case CSS_PROP_BORDER_LEFT_COLOR:
02263     case CSS_PROP_COLOR:
02264     case CSS_PROP_OUTLINE_COLOR:
02265         // this property is an extension used to get HTML4 <font> right.
02266     case CSS_PROP_SCROLLBAR_FACE_COLOR:
02267     case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
02268     case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
02269     case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
02270     case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
02271     case CSS_PROP_SCROLLBAR_TRACK_COLOR:
02272     case CSS_PROP_SCROLLBAR_ARROW_COLOR:
02273     {
02274         QColor col;
02275         if (isInherit) {
02276             HANDLE_INHERIT_COND(CSS_PROP_BACKGROUND_COLOR, backgroundColor, BackgroundColor)
02277             HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_COLOR, borderTopColor, BorderTopColor)
02278             HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_COLOR, borderBottomColor, BorderBottomColor)
02279             HANDLE_INHERIT_COND(CSS_PROP_BORDER_RIGHT_COLOR, borderRightColor, BorderRightColor)
02280             HANDLE_INHERIT_COND(CSS_PROP_BORDER_LEFT_COLOR, borderLeftColor, BorderLeftColor)
02281             HANDLE_INHERIT_COND(CSS_PROP_COLOR, color, Color)
02282             HANDLE_INHERIT_COND(CSS_PROP_OUTLINE_COLOR, outlineColor, OutlineColor)
02283             return;
02284         } else if (isInitial) {
02285             // The border/outline colors will just map to the invalid color |col| above.  This will have the
02286             // effect of forcing the use of the currentColor when it comes time to draw the borders (and of
02287             // not painting the background since the color won't be valid).
02288             if (id == CSS_PROP_COLOR)
02289                 col = RenderStyle::initialColor();
02290         } else {
02291         if(!primitiveValue )
02292         return;
02293         int ident = primitiveValue->getIdent();
02294         if ( ident ) {
02295         if ( ident == CSS_VAL__KHTML_TEXT )
02296             col = element->getDocument()->textColor();
02297         // ### should be eliminated
02298         else if ( ident == CSS_VAL_TRANSPARENT
02299                     && id != CSS_PROP_BORDER_TOP_COLOR
02300                         && id != CSS_PROP_BORDER_RIGHT_COLOR
02301                 && id != CSS_PROP_BORDER_BOTTOM_COLOR
02302                 && id != CSS_PROP_BORDER_LEFT_COLOR )
02303             col = QColor();
02304         else
02305             col = colorForCSSValue( ident );
02306         } else if ( primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR ) {
02307 #ifndef APPLE_CHANGES
02308         if(qAlpha(primitiveValue->getRGBColorValue()))
02309 #endif
02310             col.setRgb(primitiveValue->getRGBColorValue());
02311         } else {
02312         return;
02313         }
02314     }
02315         //kdDebug( 6080 ) << "applying color " << col.isValid() << endl;
02316         switch(id)
02317         {
02318         case CSS_PROP_BACKGROUND_COLOR:
02319         style->setBackgroundColor(col); break;
02320         case CSS_PROP_BORDER_TOP_COLOR:
02321             style->setBorderTopColor(col); break;
02322         case CSS_PROP_BORDER_RIGHT_COLOR:
02323             style->setBorderRightColor(col); break;
02324         case CSS_PROP_BORDER_BOTTOM_COLOR:
02325             style->setBorderBottomColor(col); break;
02326         case CSS_PROP_BORDER_LEFT_COLOR:
02327             style->setBorderLeftColor(col); break;
02328         case CSS_PROP_COLOR:
02329             style->setColor(col); break;
02330         case CSS_PROP__KHTML_TEXT_DECORATION_COLOR:
02331             style->setTextDecorationColor(col); break;
02332         case CSS_PROP_OUTLINE_COLOR:
02333             style->setOutlineColor(col); break;
02334 #ifndef APPLE_CHANGES
02335         case CSS_PROP_SCROLLBAR_FACE_COLOR:
02336             style->setPaletteColor(QPalette::Active, QColorGroup::Button, col);
02337             style->setPaletteColor(QPalette::Inactive, QColorGroup::Button, col);
02338             break;
02339         case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
02340             style->setPaletteColor(QPalette::Active, QColorGroup::Shadow, col);
02341             style->setPaletteColor(QPalette::Inactive, QColorGroup::Shadow, col);
02342             break;
02343         case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
02344             style->setPaletteColor(QPalette::Active, QColorGroup::Light, col);
02345             style->setPaletteColor(QPalette::Inactive, QColorGroup::Light, col);
02346             break;
02347         case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
02348             break;
02349         case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
02350             style->setPaletteColor(QPalette::Active, QColorGroup::Dark, col);
02351             style->setPaletteColor(QPalette::Inactive, QColorGroup::Dark, col);
02352             break;
02353         case CSS_PROP_SCROLLBAR_TRACK_COLOR:
02354             style->setPaletteColor(QPalette::Active, QColorGroup::Mid, col);
02355             style->setPaletteColor(QPalette::Inactive, QColorGroup::Mid, col);
02356             style->setPaletteColor(QPalette::Active, QColorGroup::Background, col);
02357             style->setPaletteColor(QPalette::Inactive, QColorGroup::Background, col);
02358             // fall through
02359         case CSS_PROP_SCROLLBAR_BASE_COLOR:
02360             style->setPaletteColor(QPalette::Active, QColorGroup::Base, col);
02361             style->setPaletteColor(QPalette::Inactive, QColorGroup::Base, col);
02362             break;
02363         case CSS_PROP_SCROLLBAR_ARROW_COLOR:
02364             style->setPaletteColor(QPalette::Active, QColorGroup::ButtonText, col);
02365             style->setPaletteColor(QPalette::Inactive, QColorGroup::ButtonText, col);
02366             break;
02367 #endif
02368         default:
02369             return;
02370         }
02371         return;
02372     }
02373     break;
02374 // uri || inherit
02375     case CSS_PROP_BACKGROUND_IMAGE:
02376     {
02377         HANDLE_INHERIT_AND_INITIAL(backgroundImage, BackgroundImage)
02378         if (!primitiveValue) return;
02379     style->setBackgroundImage(static_cast<CSSImageValueImpl *>(primitiveValue)->image());
02380         //kdDebug( 6080 ) << "setting image in style to " << image << endl;
02381         break;
02382     }
02383     case CSS_PROP_LIST_STYLE_IMAGE:
02384     {
02385         HANDLE_INHERIT_AND_INITIAL(listStyleImage, ListStyleImage)
02386         if (!primitiveValue) return;
02387     style->setListStyleImage(static_cast<CSSImageValueImpl *>(primitiveValue)->image());
02388         //kdDebug( 6080 ) << "setting image in list to " << image->image() << endl;
02389         break;
02390     }
02391 
02392 // length
02393     case CSS_PROP_BORDER_TOP_WIDTH:
02394     case CSS_PROP_BORDER_RIGHT_WIDTH:
02395     case CSS_PROP_BORDER_BOTTOM_WIDTH:
02396     case CSS_PROP_BORDER_LEFT_WIDTH:
02397     case CSS_PROP_OUTLINE_WIDTH:
02398     {
02399     if (isInherit) {
02400             HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_WIDTH, borderTopWidth, BorderTopWidth)
02401             HANDLE_INHERIT_COND(CSS_PROP_BORDER_RIGHT_WIDTH, borderRightWidth, BorderRightWidth)
02402             HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_WIDTH, borderBottomWidth, BorderBottomWidth)
02403             HANDLE_INHERIT_COND(CSS_PROP_BORDER_LEFT_WIDTH, borderLeftWidth, BorderLeftWidth)
02404             HANDLE_INHERIT_COND(CSS_PROP_OUTLINE_WIDTH, outlineWidth, OutlineWidth)
02405             return;
02406         }
02407         else if (isInitial) {
02408             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_TOP_WIDTH, BorderTopWidth, BorderWidth)
02409             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_RIGHT_WIDTH, BorderRightWidth, BorderWidth)
02410             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_BOTTOM_WIDTH, BorderBottomWidth, BorderWidth)
02411             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_LEFT_WIDTH, BorderLeftWidth, BorderWidth)
02412             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_OUTLINE_WIDTH, OutlineWidth, BorderWidth)
02413             return;
02414         }
02415 
02416         if(!primitiveValue) break;
02417         short width = 3;
02418         switch(primitiveValue->getIdent())
02419         {
02420         case CSS_VAL_THIN:
02421             width = 1;
02422             break;
02423         case CSS_VAL_MEDIUM:
02424             width = 3;
02425             break;
02426         case CSS_VAL_THICK:
02427             width = 5;
02428             break;
02429         case CSS_VAL_INVALID:
02430         {
02431             double widthd = primitiveValue->computeLengthFloat(style, paintDeviceMetrics);
02432             width = (int)widthd;
02433             // somewhat resemble Mozilla's granularity
02434             // this makes border-width: 0.5pt borders visible
02435             if (width == 0 && widthd >= 0.025) width++;
02436             break;
02437         }
02438         default:
02439             return;
02440         }
02441 
02442         if(width < 0) return;
02443         switch(id)
02444         {
02445         case CSS_PROP_BORDER_TOP_WIDTH:
02446             style->setBorderTopWidth(width);
02447             break;
02448         case CSS_PROP_BORDER_RIGHT_WIDTH:
02449             style->setBorderRightWidth(width);
02450             break;
02451         case CSS_PROP_BORDER_BOTTOM_WIDTH:
02452             style->setBorderBottomWidth(width);
02453             break;
02454         case CSS_PROP_BORDER_LEFT_WIDTH:
02455             style->setBorderLeftWidth(width);
02456             break;
02457         case CSS_PROP_OUTLINE_WIDTH:
02458             style->setOutlineWidth(width);
02459             break;
02460         default:
02461             return;
02462         }
02463         return;
02464     }
02465 
02466     case CSS_PROP_LETTER_SPACING:
02467     case CSS_PROP_WORD_SPACING:
02468     {
02469         if (isInherit) {
02470             HANDLE_INHERIT_COND(CSS_PROP_LETTER_SPACING, letterSpacing, LetterSpacing)
02471             HANDLE_INHERIT_COND(CSS_PROP_WORD_SPACING, wordSpacing, WordSpacing)
02472             return;
02473         } else if (isInitial) {
02474             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_LETTER_SPACING, LetterSpacing, LetterWordSpacing)
02475             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_WORD_SPACING, WordSpacing, LetterWordSpacing)
02476             return;
02477         }
02478         if(!primitiveValue) return;
02479 
02480         int width = 0;
02481         if (primitiveValue->getIdent() != CSS_VAL_NORMAL)
02482         width = primitiveValue->computeLength(style, paintDeviceMetrics);
02483 
02484         switch(id)
02485         {
02486         case CSS_PROP_LETTER_SPACING:
02487             style->setLetterSpacing(width);
02488             break;
02489         case CSS_PROP_WORD_SPACING:
02490             style->setWordSpacing(width);
02491             break;
02492             // ### needs the definitions in renderstyle
02493         default: break;
02494         }
02495         return;
02496     }
02497 
02498         // length, percent
02499     case CSS_PROP_MAX_WIDTH:
02500         // +none +inherit
02501         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
02502             apply = true;
02503     case CSS_PROP_TOP:
02504     case CSS_PROP_LEFT:
02505     case CSS_PROP_RIGHT:
02506     case CSS_PROP_BOTTOM:
02507     case CSS_PROP_WIDTH:
02508     case CSS_PROP_MIN_WIDTH:
02509     case CSS_PROP_MARGIN_TOP:
02510     case CSS_PROP_MARGIN_RIGHT:
02511     case CSS_PROP_MARGIN_BOTTOM:
02512     case CSS_PROP_MARGIN_LEFT:
02513         // +inherit +auto
02514         if(id != CSS_PROP_MAX_WIDTH && primitiveValue &&
02515            primitiveValue->getIdent() == CSS_VAL_AUTO)
02516         {
02517             //kdDebug( 6080 ) << "found value=auto" << endl;
02518             apply = true;
02519         }
02520     case CSS_PROP_PADDING_TOP:
02521     case CSS_PROP_PADDING_RIGHT:
02522     case CSS_PROP_PADDING_BOTTOM:
02523     case CSS_PROP_PADDING_LEFT:
02524     case CSS_PROP_TEXT_INDENT:
02525         // +inherit
02526     {
02527         if (isInherit) {
02528             HANDLE_INHERIT_COND(CSS_PROP_MAX_WIDTH, maxWidth, MaxWidth)
02529             HANDLE_INHERIT_COND(CSS_PROP_BOTTOM, bottom, Bottom)
02530             HANDLE_INHERIT_COND(CSS_PROP_TOP, top, Top)
02531             HANDLE_INHERIT_COND(CSS_PROP_LEFT, left, Left)
02532             HANDLE_INHERIT_COND(CSS_PROP_RIGHT, right, Right)
02533             HANDLE_INHERIT_COND(CSS_PROP_WIDTH, width, Width)
02534             HANDLE_INHERIT_COND(CSS_PROP_MIN_WIDTH, minWidth, MinWidth)
02535             HANDLE_INHERIT_COND(CSS_PROP_PADDING_TOP, paddingTop, PaddingTop)
02536             HANDLE_INHERIT_COND(CSS_PROP_PADDING_RIGHT, paddingRight, PaddingRight)
02537             HANDLE_INHERIT_COND(CSS_PROP_PADDING_BOTTOM, paddingBottom, PaddingBottom)
02538             HANDLE_INHERIT_COND(CSS_PROP_PADDING_LEFT, paddingLeft, PaddingLeft)
02539             HANDLE_INHERIT_COND(CSS_PROP_MARGIN_TOP, marginTop, MarginTop)
02540             HANDLE_INHERIT_COND(CSS_PROP_MARGIN_RIGHT, marginRight, MarginRight)
02541             HANDLE_INHERIT_COND(CSS_PROP_MARGIN_BOTTOM, marginBottom, MarginBottom)
02542             HANDLE_INHERIT_COND(CSS_PROP_MARGIN_LEFT, marginLeft, MarginLeft)
02543             HANDLE_INHERIT_COND(CSS_PROP_TEXT_INDENT, textIndent, TextIndent)
02544             return;
02545         } else if (isInitial) {
02546             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MAX_WIDTH, MaxWidth, MaxSize)
02547             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BOTTOM, Bottom, Offset)
02548             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_TOP, Top, Offset)
02549             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_LEFT, Left, Offset)
02550             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_RIGHT, Right, Offset)
02551             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_WIDTH, Width, Size)
02552             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MIN_WIDTH, MinWidth, MinSize)
02553             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_TOP, PaddingTop, Padding)
02554             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_RIGHT, PaddingRight, Padding)
02555             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_BOTTOM, PaddingBottom, Padding)
02556             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_LEFT, PaddingLeft, Padding)
02557             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_TOP, MarginTop, Margin)
02558             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_RIGHT, MarginRight, Margin)
02559             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_BOTTOM, MarginBottom, Margin)
02560             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_LEFT, MarginLeft, Margin)
02561             HANDLE_INITIAL_COND(CSS_PROP_TEXT_INDENT, TextIndent)
02562             return;
02563         }
02564 
02565         if (primitiveValue && !apply) {
02566             int type = primitiveValue->primitiveType();
02567             if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02568                 // Handle our quirky margin units if we have them.
02569                 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed,
02570                            primitiveValue->isQuirkValue());
02571             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02572                 l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02573         else if (type == CSSPrimitiveValue::CSS_HTML_RELATIVE)
02574         l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_HTML_RELATIVE)), Relative);
02575             else
02576                 return;
02577             apply = true;
02578         }
02579         if(!apply) return;
02580         switch(id)
02581             {
02582             case CSS_PROP_MAX_WIDTH:
02583                 style->setMaxWidth(l); break;
02584             case CSS_PROP_BOTTOM:
02585                 style->setBottom(l); break;
02586             case CSS_PROP_TOP:
02587                 style->setTop(l); break;
02588             case CSS_PROP_LEFT:
02589                 style->setLeft(l); break;
02590             case CSS_PROP_RIGHT:
02591                 style->setRight(l); break;
02592             case CSS_PROP_WIDTH:
02593                 style->setWidth(l); break;
02594             case CSS_PROP_MIN_WIDTH:
02595                 style->setMinWidth(l); break;
02596             case CSS_PROP_PADDING_TOP:
02597                 style->setPaddingTop(l); break;
02598             case CSS_PROP_PADDING_RIGHT:
02599                 style->setPaddingRight(l); break;
02600             case CSS_PROP_PADDING_BOTTOM:
02601                 style->setPaddingBottom(l); break;
02602             case CSS_PROP_PADDING_LEFT:
02603                 style->setPaddingLeft(l); break;
02604             case CSS_PROP_MARGIN_TOP:
02605                 style->setMarginTop(l); break;
02606             case CSS_PROP_MARGIN_RIGHT:
02607                 style->setMarginRight(l); break;
02608             case CSS_PROP_MARGIN_BOTTOM:
02609                 style->setMarginBottom(l); break;
02610             case CSS_PROP_MARGIN_LEFT:
02611                 style->setMarginLeft(l); break;
02612             case CSS_PROP_TEXT_INDENT:
02613                 style->setTextIndent(l); break;
02614             default: break;
02615             }
02616         return;
02617     }
02618 
02619     case CSS_PROP_MAX_HEIGHT:
02620         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
02621             apply = true;
02622     case CSS_PROP_HEIGHT:
02623     case CSS_PROP_MIN_HEIGHT:
02624         if(id != CSS_PROP_MAX_HEIGHT && primitiveValue &&
02625            primitiveValue->getIdent() == CSS_VAL_AUTO)
02626             apply = true;
02627         if (isInherit) {
02628             HANDLE_INHERIT_COND(CSS_PROP_MAX_HEIGHT, maxHeight, MaxHeight)
02629             HANDLE_INHERIT_COND(CSS_PROP_HEIGHT, height, Height)
02630             HANDLE_INHERIT_COND(CSS_PROP_MIN_HEIGHT, minHeight, MinHeight)
02631             return;
02632         }
02633         else if (isInitial) {
02634             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MAX_HEIGHT, MaxHeight, MaxSize)
02635             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_HEIGHT, Height, Size)
02636             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MIN_HEIGHT, MinHeight, MinSize)
02637             return;
02638         }
02639 
02640         if (primitiveValue && !apply)
02641         {
02642             int type = primitiveValue->primitiveType();
02643             if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02644                 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02645             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02646                 l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02647             else
02648                 return;
02649             apply = true;
02650         }
02651         if(!apply) return;
02652         switch(id)
02653         {
02654         case CSS_PROP_MAX_HEIGHT:
02655             style->setMaxHeight(l); break;
02656         case CSS_PROP_HEIGHT:
02657             style->setHeight(l); break;
02658         case CSS_PROP_MIN_HEIGHT:
02659             style->setMinHeight(l); break;
02660         default:
02661             return;
02662         }
02663         return;
02664 
02665         break;
02666 
02667     case CSS_PROP_VERTICAL_ALIGN:
02668         HANDLE_INHERIT_AND_INITIAL(verticalAlign, VerticalAlign)
02669         if (!primitiveValue) return;
02670         if (primitiveValue->getIdent()) {
02671       khtml::EVerticalAlign align;
02672 
02673       switch(primitiveValue->getIdent())
02674         {
02675         case CSS_VAL_TOP:
02676             align = TOP; break;
02677         case CSS_VAL_BOTTOM:
02678             align = BOTTOM; break;
02679         case CSS_VAL_MIDDLE:
02680             align = MIDDLE; break;
02681         case CSS_VAL_BASELINE:
02682             align = BASELINE; break;
02683         case CSS_VAL_TEXT_BOTTOM:
02684             align = TEXT_BOTTOM; break;
02685         case CSS_VAL_TEXT_TOP:
02686             align = TEXT_TOP; break;
02687         case CSS_VAL_SUB:
02688             align = SUB; break;
02689         case CSS_VAL_SUPER:
02690             align = SUPER; break;
02691         case CSS_VAL__KHTML_BASELINE_MIDDLE:
02692             align = BASELINE_MIDDLE; break;
02693         default:
02694             return;
02695         }
02696       style->setVerticalAlign(align);
02697       return;
02698         } else {
02699       int type = primitiveValue->primitiveType();
02700       Length l;
02701       if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02702         l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed );
02703       else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02704         l = Length( int( primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE) ), Percent );
02705 
02706       style->setVerticalAlign( LENGTH );
02707       style->setVerticalAlignLength( l );
02708     }
02709         break;
02710 
02711     case CSS_PROP_FONT_SIZE:
02712     {
02713         FontDef fontDef = style->htmlFont().fontDef;
02714         int oldSize;
02715         int size = 0;
02716 
02717     float toPix = paintDeviceMetrics->logicalDpiY()/72.;
02718     if (toPix  < 96./72.) toPix = 96./72.;
02719 
02720         int minFontSize = int(settings->minFontSize() * toPix);
02721 
02722         if(parentNode) {
02723             oldSize = parentStyle->font().pixelSize();
02724         } else
02725             oldSize = m_fontSizes[3];
02726 
02727         if (isInherit )
02728             size = oldSize;
02729         else if (isInitial)
02730             size = m_fontSizes[3];
02731         else if(primitiveValue->getIdent()) {
02732         // keywords are being used.  Pick the correct default
02733         // based off the font family.
02734 #ifdef APPLE_CHANGES
02735         QValueList<int>& fontSizes = (fontDef.genericFamily == FontDef::eMonospace) ?
02736                      m_fixedFontSizes : m_fontSizes;
02737 #else
02738         QValueList<int>& fontSizes = m_fontSizes;
02739 #endif
02740             switch(primitiveValue->getIdent())
02741             {
02742             case CSS_VAL_XX_SMALL: size = int( fontSizes[0] ); break;
02743             case CSS_VAL_X_SMALL:  size = int( fontSizes[1] ); break;
02744             case CSS_VAL_SMALL:    size = int( fontSizes[2] ); break;
02745             case CSS_VAL_MEDIUM:   size = int( fontSizes[3] ); break;
02746             case CSS_VAL_LARGE:    size = int( fontSizes[4] ); break;
02747             case CSS_VAL_X_LARGE:  size = int( fontSizes[5] ); break;
02748             case CSS_VAL_XX_LARGE: size = int( fontSizes[6] ); break;
02749             case CSS_VAL__KHTML_XXX_LARGE: size = int( fontSizes[7] ); break;
02750             case CSS_VAL_LARGER:
02751                 // ### use the next bigger standardSize!!!
02752                 size = ( oldSize * 5 ) / 4;
02753                 break;
02754             case CSS_VAL_SMALLER:
02755                 size = ( oldSize * 4 ) / 5;
02756                 break;
02757             default:
02758                 return;
02759             }
02760 
02761         } else {
02762             int type = primitiveValue->primitiveType();
02763             if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) {
02764                 if ( !khtml::printpainter && type != CSSPrimitiveValue::CSS_EMS && type != CSSPrimitiveValue::CSS_EXS &&
02765                      element && element->getDocument()->view())
02766                     size = int( primitiveValue->computeLengthFloat(parentStyle, paintDeviceMetrics) *
02767                                 element->getDocument()->view()->part()->zoomFactor() ) / 100;
02768         else
02769                     size = int( primitiveValue->computeLengthFloat(parentStyle, paintDeviceMetrics) );
02770             }
02771             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02772                 size = int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE)
02773                         * parentStyle->font().pixelSize()) / 100;
02774             else
02775                 return;
02776         }
02777 
02778         if(size < 1) return;
02779 
02780         // we never want to get smaller than the minimum font size to keep fonts readable
02781         if(size < minFontSize ) size = minFontSize;
02782 
02783         //kdDebug( 6080 ) << "computed raw font size: " << size << endl;
02784 
02785     fontDef.size = size;
02786         fontDirty |= style->setFontDef( fontDef );
02787         return;
02788     }
02789 
02790     case CSS_PROP_Z_INDEX:
02791     {
02792         HANDLE_INHERIT(zIndex, ZIndex)
02793         else if (isInitial) {
02794             style->setHasAutoZIndex();
02795             return;
02796         }
02797 
02798         if (!primitiveValue)
02799             return;
02800 
02801         if (primitiveValue->getIdent() == CSS_VAL_AUTO) {
02802             style->setHasAutoZIndex();
02803             return;
02804         }
02805 
02806         if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
02807             return; // Error case.
02808 
02809         style->setZIndex((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER));
02810         return;
02811     }
02812 
02813     case CSS_PROP_WIDOWS:
02814     {
02815         HANDLE_INHERIT_AND_INITIAL(widows, Widows)
02816         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
02817             return;
02818         style->setWidows((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER));
02819         break;
02820      }
02821 
02822     case CSS_PROP_ORPHANS:
02823     {
02824         HANDLE_INHERIT_AND_INITIAL(orphans, Orphans)
02825         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
02826             return;
02827         style->setOrphans((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER));
02828         break;
02829     }
02830 
02831 // length, percent, number
02832     case CSS_PROP_LINE_HEIGHT:
02833     {
02834         HANDLE_INHERIT_AND_INITIAL(lineHeight, LineHeight)
02835         if(!primitiveValue) return;
02836         Length lineHeight;
02837         int type = primitiveValue->primitiveType();
02838         if (primitiveValue->getIdent() == CSS_VAL_NORMAL)
02839             lineHeight = Length( -100, Percent );
02840         else if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) {
02841 #ifdef APPLE_CHANGES
02842             double multiplier = 1.0;
02843             // Scale for the font zoom factor only for types other than "em" and "ex", since those are
02844             // already based on the font size.
02845             if (type != CSSPrimitiveValue::CSS_EMS && type != CSSPrimitiveValue::CSS_EXS && view && view->part()) {
02846                 multiplier = view->part()->zoomFactor() / 100.0;
02847             }
02848             lineHeight = Length(primitiveValue->computeLength(style, paintDeviceMetrics, multiplier), Fixed);
02849 #else
02850             lineHeight = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02851 #endif
02852         } else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
02853             lineHeight = Length( ( style->font().pixelSize() * int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE)) ) / 100, Fixed );
02854         else if (type == CSSPrimitiveValue::CSS_NUMBER)
02855             lineHeight = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)*100), Percent);
02856         else
02857             return;
02858         style->setLineHeight(lineHeight);
02859         return;
02860     }
02861 
02862 // string
02863     case CSS_PROP_TEXT_ALIGN:
02864     {
02865         HANDLE_INHERIT_AND_INITIAL(textAlign, TextAlign)
02866         if (!primitiveValue) return;
02867         if (primitiveValue->getIdent())
02868             style->setTextAlign( (ETextAlign) (primitiveValue->getIdent() - CSS_VAL__KHTML_AUTO) );
02869     return;
02870     }
02871 
02872 // rect
02873     case CSS_PROP_CLIP:
02874     {
02875     Length top;
02876     Length right;
02877     Length bottom;
02878     Length left;
02879         bool hasClip = true;
02880     if (isInherit) {
02881             if (parentStyle->hasClip()) {
02882                 top = parentStyle->clipTop();
02883                 right = parentStyle->clipRight();
02884                 bottom = parentStyle->clipBottom();
02885                 left = parentStyle->clipLeft();
02886             }
02887             else {
02888                 hasClip = false;
02889                 top = right = bottom = left = Length();
02890             }
02891         } else if (isInitial) {
02892             hasClip = false;
02893             top = right = bottom = left = Length();
02894         } else if ( !primitiveValue ) {
02895         break;
02896     } else if ( primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RECT ) {
02897         RectImpl *rect = primitiveValue->getRectValue();
02898         if ( !rect )
02899         break;
02900         top = convertToLength( rect->top(), style, paintDeviceMetrics );
02901         right = convertToLength( rect->right(), style, paintDeviceMetrics );
02902         bottom = convertToLength( rect->bottom(), style, paintDeviceMetrics );
02903         left = convertToLength( rect->left(), style, paintDeviceMetrics );
02904 
02905     } else if ( primitiveValue->getIdent() != CSS_VAL_AUTO ) {
02906         break;
02907     }
02908 //  qDebug("setting clip top to %d", top.value );
02909 //  qDebug("setting clip right to %d", right.value );
02910 //  qDebug("setting clip bottom to %d", bottom.value );
02911 //  qDebug("setting clip left to %d", left.value );
02912     style->setClip(top, right, bottom, left );
02913     style->setHasClip(hasClip);
02914         // rect, ident
02915         break;
02916     }
02917 
02918 // lists
02919     case CSS_PROP_CONTENT:
02920         // list of string, uri, counter, attr, i
02921     {
02922         // FIXME: In CSS3, it will be possible to inherit content.  In CSS2 it is not.  This
02923         // note is a reminder that eventually "inherit" needs to be supported.
02924         if (!(style->styleType()==RenderStyle::BEFORE ||
02925                 style->styleType()==RenderStyle::AFTER))
02926             break;
02927 
02928         if (isInitial) {
02929             if (style->contentData())
02930                 style->contentData()->clearContent();
02931             return;
02932         }
02933 
02934         if(!value->isValueList()) return;
02935         CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
02936         int len = list->length();
02937 
02938         for(int i = 0; i < len; i++) {
02939             CSSValueImpl *item = list->item(i);
02940             if(!item->isPrimitiveValue()) continue;
02941             CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item);
02942             if(val->primitiveType()==CSSPrimitiveValue::CSS_STRING)
02943             {
02944                 style->setContent(val->getStringValue(), i != 0);
02945             }
02946             else if (val->primitiveType()==CSSPrimitiveValue::CSS_ATTR)
02947             {
02948 #ifdef APPLE_CHANGES
02949                 int attrID = element->getDocument()->attrId(0, val->getStringValue(), false);
02950                 if (attrID)
02951                     style->setContent(element->getAttribute(attrID).implementation(), i != 0);
02952 #else
02953                 int attrID = element->getDocument()->getId(NodeImpl::AttributeId, val->getStringValue(), false, true);
02954                 if (attrID)
02955                     style->setContent(element->getAttribute(attrID).implementation(), i != 0);
02956 #endif
02957             }
02958             else if (val->primitiveType()==CSSPrimitiveValue::CSS_URI)
02959             {
02960                 CSSImageValueImpl *image = static_cast<CSSImageValueImpl *>(val);
02961                 style->setContent(image->image(), i != 0);
02962             }
02963 
02964         }
02965         break;
02966     }
02967 
02968     case CSS_PROP_COUNTER_INCREMENT:
02969         // list of CSS2CounterIncrement
02970     case CSS_PROP_COUNTER_RESET:
02971         // list of CSS2CounterReset
02972         break;
02973     case CSS_PROP_FONT_FAMILY:
02974         // list of strings and ids
02975     {
02976         if (isInherit) {
02977             FontDef parentFontDef = parentStyle->htmlFont().fontDef;
02978             FontDef fontDef = style->htmlFont().fontDef;
02979             fontDef.family = parentFontDef.family;
02980             if (style->setFontDef(fontDef))
02981                 fontDirty = true;
02982             return;
02983         }
02984         else if (isInitial) {
02985             FontDef fontDef = style->htmlFont().fontDef;
02986             FontDef initialDef = FontDef();
02987 #ifdef APPLE_CHANGES
02988             fontDef.family = initialDef.firstFamily();
02989 #else
02990             fontDef.family = QString::null;
02991 #endif
02992             if (style->setFontDef(fontDef))
02993                 fontDirty = true;
02994             return;
02995         }
02996         if(!value->isValueList()) return;
02997     FontDef fontDef = style->htmlFont().fontDef;
02998         CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
02999         int len = list->length();
03000         for(int i = 0; i < len; i++) {
03001             CSSValueImpl *item = list->item(i);
03002             if(!item->isPrimitiveValue()) continue;
03003             CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item);
03004         QString face;
03005             if( val->primitiveType() == CSSPrimitiveValue::CSS_STRING )
03006         face = static_cast<FontFamilyValueImpl *>(val)->fontName();
03007         else if ( val->primitiveType() == CSSPrimitiveValue::CSS_IDENT ) {
03008         switch( val->getIdent() ) {
03009         case CSS_VAL_SERIF:
03010             face = settings->serifFontName();
03011             break;
03012         case CSS_VAL_SANS_SERIF:
03013             face = settings->sansSerifFontName();
03014             break;
03015         case CSS_VAL_CURSIVE:
03016             face = settings->cursiveFontName();
03017             break;
03018         case CSS_VAL_FANTASY:
03019             face = settings->fantasyFontName();
03020             break;
03021         case CSS_VAL_MONOSPACE:
03022             face = settings->fixedFontName();
03023             break;
03024         default:
03025             return;
03026         }
03027         } else {
03028         return;
03029         }
03030         if ( !face.isEmpty() ) {
03031         fontDef.family = face;
03032         fontDirty |= style->setFontDef( fontDef );
03033                 return;
03034         }
03035     }
03036         break;
03037     }
03038     case CSS_PROP_QUOTES:
03039         // list of strings or i
03040     case CSS_PROP_SIZE:
03041         // ### look up
03042       break;
03043     case CSS_PROP_TEXT_DECORATION: {
03044         // list of ident
03045         HANDLE_INHERIT_AND_INITIAL(textDecoration, TextDecoration)
03046         int t = RenderStyle::initialTextDecoration();
03047         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) {
03048         // do nothing
03049     } else {
03050         if(!value->isValueList()) return;
03051         CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
03052         int len = list->length();
03053         for(int i = 0; i < len; i++)
03054         {
03055         CSSValueImpl *item = list->item(i);
03056         if(!item->isPrimitiveValue()) continue;
03057         primitiveValue = static_cast<CSSPrimitiveValueImpl *>(item);
03058         switch(primitiveValue->getIdent())
03059         {
03060             case CSS_VAL_NONE:
03061             t = TDNONE; break;
03062             case CSS_VAL_UNDERLINE:
03063             t |= UNDERLINE; break;
03064             case CSS_VAL_OVERLINE:
03065             t |= OVERLINE; break;
03066             case CSS_VAL_LINE_THROUGH:
03067             t |= LINE_THROUGH; break;
03068             case CSS_VAL_BLINK:
03069             t |= BLINK; break;
03070             default:
03071             return;
03072         }
03073         }
03074         }
03075     style->setTextDecoration(t);
03076         break;
03077     }
03078     case CSS_PROP__KHTML_FLOW_MODE:
03079         HANDLE_INHERIT_AND_INITIAL(flowAroundFloats, FlowAroundFloats)
03080         if (!primitiveValue) return;
03081         if (primitiveValue->getIdent()) {
03082             style->setFlowAroundFloats( primitiveValue->getIdent() == CSS_VAL__KHTML_AROUND_FLOATS );
03083             return;
03084         }
03085         break;
03086     case CSS_PROP__KHTML_USER_INPUT: {
03087         if(value->cssValueType() == CSSValue::CSS_INHERIT)
03088         {
03089             if(!parentNode) return;
03090             style->setUserInput(parentStyle->userInput());
03091 //      kdDebug() << "UI erm" << endl;
03092             return;
03093         }
03094         if(!primitiveValue) return;
03095         int id = primitiveValue->getIdent();
03096     if (id == CSS_VAL_NONE)
03097         style->setUserInput(UI_NONE);
03098     else
03099         style->setUserInput(EUserInput(id - CSS_VAL_ENABLED));
03100 //  kdDebug(6080) << "userInput: " << style->userEdit() << endl;
03101     return;
03102     }
03103 
03104 // shorthand properties
03105     case CSS_PROP_BACKGROUND:
03106         if (isInherit) {
03107             style->setBackgroundColor(parentStyle->backgroundColor());
03108             style->setBackgroundImage(parentStyle->backgroundImage());
03109             style->setBackgroundRepeat(parentStyle->backgroundRepeat());
03110             style->setBackgroundAttachment(parentStyle->backgroundAttachment());
03111             style->setBackgroundXPosition(parentStyle->backgroundXPosition());
03112             style->setBackgroundYPosition(parentStyle->backgroundYPosition());
03113         }
03114         else if (isInitial) {
03115             style->setBackgroundColor(QColor());
03116             style->setBackgroundImage(RenderStyle::initialBackgroundImage());
03117             style->setBackgroundRepeat(RenderStyle::initialBackgroundRepeat());
03118             style->setBackgroundAttachment(RenderStyle::initialBackgroundAttachment());
03119             style->setBackgroundXPosition(RenderStyle::initialBackgroundXPosition());
03120             style->setBackgroundYPosition(RenderStyle::initialBackgroundYPosition());
03121         }
03122         break;
03123     case CSS_PROP_BORDER:
03124     case CSS_PROP_BORDER_STYLE:
03125     case CSS_PROP_BORDER_WIDTH:
03126     case CSS_PROP_BORDER_COLOR:
03127         if(id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_COLOR)
03128         {
03129              if (isInherit) {
03130                 style->setBorderTopColor(parentStyle->borderTopColor());
03131                 style->setBorderBottomColor(parentStyle->borderBottomColor());
03132                 style->setBorderLeftColor(parentStyle->borderLeftColor());
03133                 style->setBorderRightColor(parentStyle->borderRightColor());
03134             }
03135             else if (isInitial) {
03136                 style->setBorderTopColor(QColor()); // Reset to invalid color so currentColor is used instead.
03137                 style->setBorderBottomColor(QColor());
03138                 style->setBorderLeftColor(QColor());
03139                 style->setBorderRightColor(QColor());
03140             }
03141         }
03142         if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_STYLE)
03143         {
03144             if (isInherit) {
03145                 style->setBorderTopStyle(parentStyle->borderTopStyle());
03146                 style->setBorderBottomStyle(parentStyle->borderBottomStyle());
03147                 style->setBorderLeftStyle(parentStyle->borderLeftStyle());
03148                 style->setBorderRightStyle(parentStyle->borderRightStyle());
03149             }
03150             else if (isInitial) {
03151                 style->setBorderTopStyle(RenderStyle::initialBorderStyle());
03152                 style->setBorderBottomStyle(RenderStyle::initialBorderStyle());
03153                 style->setBorderLeftStyle(RenderStyle::initialBorderStyle());
03154                 style->setBorderRightStyle(RenderStyle::initialBorderStyle());
03155             }
03156         }
03157         if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_WIDTH)
03158         {
03159             if (isInherit) {
03160                 style->setBorderTopWidth(parentStyle->borderTopWidth());
03161                 style->setBorderBottomWidth(parentStyle->borderBottomWidth());
03162                 style->setBorderLeftWidth(parentStyle->borderLeftWidth());
03163                 style->setBorderRightWidth(parentStyle->borderRightWidth());
03164             }
03165             else if (isInitial) {
03166                 style->setBorderTopWidth(RenderStyle::initialBorderWidth());
03167                 style->setBorderBottomWidth(RenderStyle::initialBorderWidth());
03168                 style->setBorderLeftWidth(RenderStyle::initialBorderWidth());
03169                 style->setBorderRightWidth(RenderStyle::initialBorderWidth());
03170             }
03171         }
03172         return;
03173     case CSS_PROP_BORDER_TOP:
03174         if ( isInherit ) {
03175             style->setBorderTopColor(parentStyle->borderTopColor());
03176             style->setBorderTopStyle(parentStyle->borderTopStyle());
03177             style->setBorderTopWidth(parentStyle->borderTopWidth());
03178         } else if (isInitial)
03179             style->resetBorderTop();
03180         return;
03181     case CSS_PROP_BORDER_RIGHT:
03182         if (isInherit) {
03183             style->setBorderRightColor(parentStyle->borderRightColor());
03184             style->setBorderRightStyle(parentStyle->borderRightStyle());
03185             style->setBorderRightWidth(parentStyle->borderRightWidth());
03186         }
03187         else if (isInitial)
03188             style->resetBorderRight();
03189         return;
03190     case CSS_PROP_BORDER_BOTTOM:
03191         if (isInherit) {
03192             style->setBorderBottomColor(parentStyle->borderBottomColor());
03193             style->setBorderBottomStyle(parentStyle->borderBottomStyle());
03194             style->setBorderBottomWidth(parentStyle->borderBottomWidth());
03195         }
03196         else if (isInitial)
03197             style->resetBorderBottom();
03198         return;
03199     case CSS_PROP_BORDER_LEFT:
03200         if (isInherit) {
03201             style->setBorderLeftColor(parentStyle->borderLeftColor());
03202             style->setBorderLeftStyle(parentStyle->borderLeftStyle());
03203             style->setBorderLeftWidth(parentStyle->borderLeftWidth());
03204         }
03205         else if (isInitial)
03206             style->resetBorderLeft();
03207         return;
03208     case CSS_PROP_MARGIN:
03209         if (isInherit) {
03210             style->setMarginTop(parentStyle->marginTop());
03211             style->setMarginBottom(parentStyle->marginBottom());
03212             style->setMarginLeft(parentStyle->marginLeft());
03213             style->setMarginRight(parentStyle->marginRight());
03214         }
03215         else if (isInitial)
03216             style->resetMargin();
03217         return;
03218     case CSS_PROP_PADDING:
03219         if (isInherit) {
03220             style->setPaddingTop(parentStyle->paddingTop());
03221             style->setPaddingBottom(parentStyle->paddingBottom());
03222             style->setPaddingLeft(parentStyle->paddingLeft());
03223             style->setPaddingRight(parentStyle->paddingRight());
03224         }
03225         else if (isInitial)
03226             style->resetPadding();
03227         return;
03228     case CSS_PROP_FONT:
03229         if ( isInherit ) {
03230             FontDef fontDef = parentStyle->htmlFont().fontDef;
03231         style->setLineHeight( parentStyle->lineHeight() );
03232         fontDirty |= style->setFontDef( fontDef );
03233         } else if (isInitial) {
03234             FontDef fontDef;
03235             style->setLineHeight(RenderStyle::initialLineHeight());
03236             if (style->setFontDef( fontDef ))
03237                 fontDirty = true;
03238     } else if ( value->isFontValue() ) {
03239         FontValueImpl *font = static_cast<FontValueImpl *>(value);
03240         if ( !font->style || !font->variant || !font->weight ||
03241          !font->size || !font->lineHeight || !font->family )
03242         return;
03243         applyRule( CSS_PROP_FONT_STYLE, font->style );
03244         applyRule( CSS_PROP_FONT_VARIANT, font->variant );
03245         applyRule( CSS_PROP_FONT_WEIGHT, font->weight );
03246         applyRule( CSS_PROP_FONT_SIZE, font->size );
03247 
03248             // Line-height can depend on font().pixelSize(), so we have to update the font
03249             // before we evaluate line-height, e.g., font: 1em/1em.  FIXME: Still not
03250             // good enough: style="font:1em/1em; font-size:36px" should have a line-height of 36px.
03251             if (fontDirty)
03252                 CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics );
03253 
03254         applyRule( CSS_PROP_LINE_HEIGHT, font->lineHeight );
03255         applyRule( CSS_PROP_FONT_FAMILY, font->family );
03256     }
03257     return;
03258 
03259     case CSS_PROP_LIST_STYLE:
03260         if (isInherit) {
03261             style->setListStyleType(parentStyle->listStyleType());
03262             style->setListStyleImage(parentStyle->listStyleImage());
03263             style->setListStylePosition(parentStyle->listStylePosition());
03264         }
03265         else if (isInitial) {
03266             style->setListStyleType(RenderStyle::initialListStyleType());
03267             style->setListStyleImage(RenderStyle::initialListStyleImage());
03268             style->setListStylePosition(RenderStyle::initialListStylePosition());
03269         }
03270         break;
03271     case CSS_PROP_OUTLINE:
03272         if (isInherit) {
03273             style->setOutlineWidth(parentStyle->outlineWidth());
03274             style->setOutlineColor(parentStyle->outlineColor());
03275             style->setOutlineStyle(parentStyle->outlineStyle());
03276         }
03277         else if (isInitial)
03278             style->resetOutline();
03279         break;
03280     case CSS_PROP_BOX_SIZING:
03281         HANDLE_INHERIT(boxSizing, BoxSizing)
03282         if (!primitiveValue) return;
03283         if (primitiveValue->getIdent() == CSS_VAL_CONTENT_BOX)
03284             style->setBoxSizing(CONTENT_BOX);
03285         else
03286         if (primitiveValue->getIdent() == CSS_VAL_BORDER_BOX)
03287             style->setBoxSizing(BORDER_BOX);
03288         break;
03289     case CSS_PROP__KHTML_MARQUEE:
03290         if (value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
03291         style->setMarqueeDirection(parentStyle->marqueeDirection());
03292         style->setMarqueeIncrement(parentStyle->marqueeIncrement());
03293         style->setMarqueeSpeed(parentStyle->marqueeSpeed());
03294         style->setMarqueeLoopCount(parentStyle->marqueeLoopCount());
03295         style->setMarqueeBehavior(parentStyle->marqueeBehavior());
03296         break;
03297     case CSS_PROP__KHTML_MARQUEE_REPETITION: {
03298         HANDLE_INHERIT_AND_INITIAL(marqueeLoopCount, MarqueeLoopCount)
03299         if (!primitiveValue) return;
03300         if (primitiveValue->getIdent() == CSS_VAL_INFINITE)
03301             style->setMarqueeLoopCount(-1); // -1 means repeat forever.
03302         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
03303             style->setMarqueeLoopCount((int)(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)));
03304         break;
03305     }
03306     case CSS_PROP__KHTML_MARQUEE_SPEED: {
03307         HANDLE_INHERIT_AND_INITIAL(marqueeSpeed, MarqueeSpeed)
03308         if (!primitiveValue) return;
03309         if (primitiveValue->getIdent()) {
03310             switch (primitiveValue->getIdent())
03311             {
03312                 case CSS_VAL_SLOW:
03313                     style->setMarqueeSpeed(500); // 500 msec.
03314                     break;
03315                 case CSS_VAL_NORMAL:
03316                     style->setMarqueeSpeed(85); // 85msec. The WinIE default.
03317                     break;
03318                 case CSS_VAL_FAST:
03319                     style->setMarqueeSpeed(10); // 10msec. Super fast.
03320                     break;
03321             }
03322         }
03323         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S)
03324             style->setMarqueeSpeed(int(1000*primitiveValue->floatValue(CSSPrimitiveValue::CSS_S)));
03325         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_MS)
03326             style->setMarqueeSpeed(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_MS)));
03327         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) // For scrollamount support.
03328             style->setMarqueeSpeed(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)));
03329         break;
03330     }
03331     case CSS_PROP__KHTML_MARQUEE_INCREMENT: {
03332         HANDLE_INHERIT_AND_INITIAL(marqueeIncrement, MarqueeIncrement)
03333         if (!primitiveValue) return;
03334         if (primitiveValue->getIdent()) {
03335             switch (primitiveValue->getIdent())
03336             {
03337                 case CSS_VAL_SMALL:
03338                     style->setMarqueeIncrement(Length(1, Fixed)); // 1px.
03339                     break;
03340                 case CSS_VAL_NORMAL:
03341                     style->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default.
03342                     break;
03343                 case CSS_VAL_LARGE:
03344                     style->setMarqueeIncrement(Length(36, Fixed)); // 36px.
03345                     break;
03346             }
03347         }
03348         else {
03349             bool ok = true;
03350             Length l = convertToLength(primitiveValue, style, paintDeviceMetrics, &ok);
03351             if (ok)
03352                 style->setMarqueeIncrement(l);
03353         }
03354         break;
03355     }
03356     case CSS_PROP__KHTML_MARQUEE_STYLE: {
03357         HANDLE_INHERIT_AND_INITIAL(marqueeBehavior, MarqueeBehavior)
03358         if (!primitiveValue || !primitiveValue->getIdent()) return;
03359         switch (primitiveValue->getIdent())
03360         {
03361             case CSS_VAL_NONE:
03362                 style->setMarqueeBehavior(MNONE);
03363                 break;
03364             case CSS_VAL_SCROLL:
03365                 style->setMarqueeBehavior(MSCROLL);
03366                 break;
03367             case CSS_VAL_SLIDE:
03368                 style->setMarqueeBehavior(MSLIDE);
03369                 break;
03370             case CSS_VAL_ALTERNATE:
03371                 style->setMarqueeBehavior(MALTERNATE);
03372                 break;
03373             case CSS_VAL_UNFURL:
03374                 style->setMarqueeBehavior(MUNFURL);
03375                 break;
03376         }
03377         break;
03378     }
03379     case CSS_PROP__KHTML_MARQUEE_DIRECTION: {
03380         HANDLE_INHERIT_AND_INITIAL(marqueeDirection, MarqueeDirection)
03381         if (!primitiveValue || !primitiveValue->getIdent()) return;
03382         switch (primitiveValue->getIdent())
03383         {
03384             case CSS_VAL_FORWARDS:
03385                 style->setMarqueeDirection(MFORWARD);
03386                 break;
03387             case CSS_VAL_BACKWARDS:
03388                 style->setMarqueeDirection(MBACKWARD);
03389                 break;
03390             case CSS_VAL_AUTO:
03391                 style->setMarqueeDirection(MAUTO);
03392                 break;
03393             case CSS_VAL_AHEAD:
03394             case CSS_VAL_UP: // We don't support vertical languages, so AHEAD just maps to UP.
03395                 style->setMarqueeDirection(MUP);
03396                 break;
03397             case CSS_VAL_REVERSE:
03398             case CSS_VAL_DOWN: // REVERSE just maps to DOWN, since we don't do vertical text.
03399                 style->setMarqueeDirection(MDOWN);
03400                 break;
03401             case CSS_VAL_LEFT:
03402                 style->setMarqueeDirection(MLEFT);
03403                 break;
03404             case CSS_VAL_RIGHT:
03405                 style->setMarqueeDirection(MRIGHT);
03406                 break;
03407         }
03408         break;
03409     }
03410     default:
03411         return;
03412     }
03413 }
03414 
03415 #ifdef APPLE_CHANGES
03416 void CSSStyleSelector::checkForGenericFamilyChange(RenderStyle* aStyle, RenderStyle* aParentStyle)
03417 {
03418   const FontDef& childFont = aStyle->htmlFont().fontDef;
03419 
03420   if (childFont.sizeSpecified || !aParentStyle)
03421     return;
03422 
03423   const FontDef& parentFont = aParentStyle->htmlFont().fontDef;
03424 
03425   if (childFont.genericFamily == parentFont.genericFamily)
03426     return;
03427 
03428   // For now, lump all families but monospace together.
03429   if (childFont.genericFamily != FontDef::eMonospace &&
03430       parentFont.genericFamily != FontDef::eMonospace)
03431     return;
03432 
03433   // We know the parent is monospace or the child is monospace, and that font
03434   // size was unspecified.  We want to alter our font size to use the correct
03435   // "medium" font for our family.
03436   float size = 0;
03437   int minFontSize = settings->minFontSize();
03438   size = (childFont.genericFamily == FontDef::eMonospace) ? m_fixedFontSizes[3] : m_fontSizes[3];
03439   int isize = (int)size;
03440   if (isize < minFontSize)
03441     isize = minFontSize;
03442 
03443   FontDef newFontDef(childFont);
03444   newFontDef.size = isize;
03445   aStyle->setFontDef(newFontDef);
03446 }
03447 #endif
03448 
03449 } // namespace khtml
KDE Logo
This file is part of the documentation for khtml Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Jul 22 10:18:29 2005 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003