khtml Library API Documentation

cssstyleselector.cpp

00001 
00022 #include "css/cssstyleselector.h"
00023 #include "rendering/render_style.h"
00024 #include "css/css_stylesheetimpl.h"
00025 #include "css/css_ruleimpl.h"
00026 #include "css/css_valueimpl.h"
00027 #include "css/csshelper.h"
00028 #include "rendering/render_object.h"
00029 #include "html/html_documentimpl.h"
00030 #include "xml/dom_elementimpl.h"
00031 #include "dom/css_rule.h"
00032 #include "dom/css_value.h"
00033 #include "khtml_factory.h"
00034 #include "khtmlpart_p.h"
00035 using namespace khtml;
00036 using namespace DOM;
00037 
00038 #include "css/cssproperties.h"
00039 #include "css/cssvalues.h"
00040 
00041 #include "misc/khtmllayout.h"
00042 #include "khtml_settings.h"
00043 #include "misc/htmlhashes.h"
00044 #include "misc/helper.h"
00045 #include "misc/loader.h"
00046 
00047 #include "rendering/font.h"
00048 
00049 #include "khtmlview.h"
00050 #include "khtml_part.h"
00051 
00052 #include <kstandarddirs.h>
00053 #include <kcharsets.h>
00054 #include <kglobal.h>
00055 #include <qfile.h>
00056 #include <qfontdatabase.h>
00057 #include <qfontinfo.h>
00058 #include <qvaluelist.h>
00059 #include <qstring.h>
00060 #include <kdebug.h>
00061 #include <kurl.h>
00062 #include <qdatetime.h>
00063 #include <assert.h>
00064 #include <qpaintdevicemetrics.h>
00065 #include <qintcache.h>
00066 #include <stdlib.h>
00067 
00068 CSSStyleSelectorList *CSSStyleSelector::defaultStyle = 0;
00069 CSSStyleSelectorList *CSSStyleSelector::defaultPrintStyle = 0;
00070 CSSStyleSheetImpl *CSSStyleSelector::defaultSheet = 0;
00071 
00072 enum PseudoState { PseudoUnknown, PseudoNone, PseudoLink, PseudoVisited};
00073 static PseudoState pseudoState;
00074 
00075 CSSStyleSelector::CSSStyleSelector( DocumentImpl* doc, QString userStyleSheet, StyleSheetListImpl *styleSheets,
00076                                     const KURL &url, bool _strictParsing )
00077 {
00078     init();
00079 
00080     KHTMLView* view = doc->view();
00081     strictParsing = _strictParsing;
00082     settings = view ? view->part()->settings() : 0;
00083     if(!defaultStyle) loadDefaultStyle(settings);
00084     m_medium = view ? view->mediaType() : "all";
00085 
00086     selectors = 0;
00087     selectorCache = 0;
00088     properties = 0;
00089     userStyle = 0;
00090     userSheet = 0;
00091     paintDeviceMetrics = doc->paintDeviceMetrics();
00092 
00093     if(paintDeviceMetrics) // this may be null, not everyone uses khtmlview (Niko)
00094         computeFontSizes(paintDeviceMetrics, view ? view->part()->zoomFactor() : 100);
00095 
00096     if ( !userStyleSheet.isEmpty() ) {
00097         userSheet = new DOM::CSSStyleSheetImpl(doc);
00098         userSheet->parseString( DOMString( userStyleSheet ) );
00099 
00100         userStyle = new CSSStyleSelectorList();
00101         userStyle->append( userSheet, m_medium );
00102     }
00103 
00104     // add stylesheets from document
00105     authorStyle = new CSSStyleSelectorList();
00106 
00107 
00108     QPtrListIterator<StyleSheetImpl> it( styleSheets->styleSheets );
00109     for ( ; it.current(); ++it ) {
00110         if ( it.current()->isCSSStyleSheet() ) {
00111             authorStyle->append( static_cast<CSSStyleSheetImpl*>( it.current() ),
00112                                  m_medium );
00113         }
00114     }
00115 
00116     buildLists();
00117 
00118     //kdDebug( 6080 ) << "number of style sheets in document " << authorStyleSheets.count() << endl;
00119     //kdDebug( 6080 ) << "CSSStyleSelector: author style has " << authorStyle->count() << " elements"<< endl;
00120 
00121     KURL u = url;
00122 
00123     u.setQuery( QString::null );
00124     u.setRef( QString::null );
00125     encodedurl.file = u.url();
00126     int pos = encodedurl.file.findRev('/');
00127     encodedurl.path = encodedurl.file;
00128     if ( pos > 0 ) {
00129     encodedurl.path.truncate( pos );
00130     encodedurl.path += '/';
00131     }
00132     u.setPath( QString::null );
00133     encodedurl.host = u.url();
00134 
00135     //kdDebug() << "CSSStyleSelector::CSSStyleSelector encoded url " << encodedurl.path << endl;
00136 }
00137 
00138 CSSStyleSelector::CSSStyleSelector( CSSStyleSheetImpl *sheet )
00139 {
00140     init();
00141 
00142     if(!defaultStyle) loadDefaultStyle();
00143     m_medium = sheet->doc()->view()->mediaType();
00144 
00145     authorStyle = new CSSStyleSelectorList();
00146     authorStyle->append( sheet, m_medium );
00147 }
00148 
00149 void CSSStyleSelector::init()
00150 {
00151     element = 0;
00152     settings = 0;
00153     paintDeviceMetrics = 0;
00154     propsToApply = (CSSOrderedProperty **)malloc(128*sizeof(CSSOrderedProperty *));
00155     pseudoProps = (CSSOrderedProperty **)malloc(128*sizeof(CSSOrderedProperty *));
00156     propsToApplySize = 128;
00157     pseudoPropsSize = 128;
00158 }
00159 
00160 CSSStyleSelector::~CSSStyleSelector()
00161 {
00162     clearLists();
00163     delete authorStyle;
00164     delete userStyle;
00165     delete userSheet;
00166     free(propsToApply);
00167     free(pseudoProps);
00168 }
00169 
00170 void CSSStyleSelector::addSheet( CSSStyleSheetImpl *sheet )
00171 {
00172     m_medium = sheet->doc()->view()->mediaType();
00173     authorStyle->append( sheet, m_medium );
00174 }
00175 
00176 void CSSStyleSelector::loadDefaultStyle(const KHTMLSettings *s)
00177 {
00178     if(defaultStyle) return;
00179 
00180     QFile f(locate( "data", "khtml/css/html4.css" ) );
00181     f.open(IO_ReadOnly);
00182 
00183     QCString file( f.size()+1 );
00184     int readbytes = f.readBlock( file.data(), f.size() );
00185     f.close();
00186     if ( readbytes >= 0 )
00187         file[readbytes] = '\0';
00188 
00189     QString style = QString::fromLatin1( file.data() );
00190     if(s)
00191         style += s->settingsToCSS();
00192     DOMString str(style);
00193 
00194     defaultSheet = new DOM::CSSStyleSheetImpl((DOM::CSSStyleSheetImpl * ) 0);
00195     defaultSheet->parseString( str );
00196 
00197     defaultStyle = new CSSStyleSelectorList();
00198     defaultStyle->append( defaultSheet );
00199 
00200     defaultPrintStyle = new CSSStyleSelectorList();
00201     defaultPrintStyle->append( defaultSheet, "print" );
00202     //kdDebug() << "CSSStyleSelector: default style has " << defaultStyle->count() << " elements"<< endl;
00203 }
00204 
00205 void CSSStyleSelector::clear()
00206 {
00207     delete defaultStyle;
00208     delete defaultPrintStyle;
00209     delete defaultSheet;
00210     defaultStyle = 0;
00211     defaultPrintStyle = 0;
00212     defaultSheet = 0;
00213 }
00214 
00215 #define MAXFONTSIZES 15
00216 
00217 void CSSStyleSelector::computeFontSizes(QPaintDeviceMetrics* paintDeviceMetrics,  int zoomFactor)
00218 {
00219     // ### get rid of float / double
00220     float toPix = paintDeviceMetrics->logicalDpiY()/72.;
00221     if (toPix  < 96./72.) toPix = 96./72.;
00222 
00223     m_fontSizes.clear();
00224     const float factor = 1.2;
00225     float scale = 1.0 / (factor*factor*factor);
00226     float mediumFontSize;
00227     float minFontSize;
00228     if (!khtml::printpainter) {
00229         scale *= zoomFactor / 100.0;
00230         mediumFontSize = settings->mediumFontSize() * toPix;
00231         minFontSize = settings->minFontSize() * toPix;
00232     }
00233     else {
00234         // ## depending on something / configurable ?
00235         mediumFontSize = 12;
00236         minFontSize = 6;
00237     }
00238 
00239     for ( int i = 0; i < MAXFONTSIZES; i++ ) {
00240         m_fontSizes << int(KMAX( mediumFontSize * scale + 0.5f, minFontSize));
00241         scale *= factor;
00242     }
00243 }
00244 
00245 #undef MAXFONTSIZES
00246 
00247 static inline void bubbleSort( CSSOrderedProperty **b, CSSOrderedProperty **e )
00248 {
00249     while( b < e ) {
00250     bool swapped = FALSE;
00251         CSSOrderedProperty **y = e+1;
00252     CSSOrderedProperty **x = e;
00253         CSSOrderedProperty **swappedPos = 0;
00254     do {
00255         if ( !((**(--x)) < (**(--y))) ) {
00256         swapped = TRUE;
00257                 swappedPos = x;
00258                 CSSOrderedProperty *tmp = *y;
00259                 *y = *x;
00260                 *x = tmp;
00261         }
00262     } while( x != b );
00263     if ( !swapped ) break;
00264         b = swappedPos + 1;
00265     }
00266 }
00267 
00268 RenderStyle *CSSStyleSelector::styleForElement(ElementImpl *e, int state)
00269 {
00270     // set some variables we will need
00271     dynamicState = state;
00272     usedDynamicStates = StyleSelector::None;
00273     pseudoState = PseudoUnknown;
00274 
00275     element = e;
00276     parentNode = e->parentNode();
00277     parentStyle = ( parentNode && parentNode->renderer()) ? parentNode->renderer()->style() : 0;
00278     view = element->getDocument()->view();
00279     part = view->part();
00280     settings = part->settings();
00281     paintDeviceMetrics = element->getDocument()->paintDeviceMetrics();
00282 
00283     unsigned int numPropsToApply = 0;
00284     unsigned int numPseudoProps = 0;
00285 
00286     // try to sort out most style rules as early as possible.
00287     // ### implement CSS3 namespace support
00288     int cssTagId = (e->id() & NodeImpl_IdLocalMask);
00289     int smatch = 0;
00290     int schecked = 0;
00291 
00292     for ( unsigned int i = 0; i < selectors_size; i++ ) {
00293     int tag = selectors[i]->tag;
00294     if ( cssTagId == tag || tag == -1 ) {
00295         ++schecked;
00296 
00297         checkSelector( i, e );
00298 
00299         if ( selectorCache[i].state == Applies ) {
00300         ++smatch;
00301 
00302         //qDebug("adding property" );
00303         for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 )
00304             for ( unsigned int j = 0; j < (unsigned int )selectorCache[i].props[p+1]; ++j ) {
00305                         if (numPropsToApply >= propsToApplySize ) {
00306                             propsToApplySize *= 2;
00307                 propsToApply = (CSSOrderedProperty **)realloc( propsToApply, propsToApplySize*sizeof( CSSOrderedProperty * ) );
00308             }
00309             propsToApply[numPropsToApply++] = properties[selectorCache[i].props[p]+j];
00310             }
00311         } else if ( selectorCache[i].state == AppliesPseudo ) {
00312         for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 )
00313             for ( unsigned int j = 0; j < (unsigned int) selectorCache[i].props[p+1]; ++j ) {
00314                         if (numPseudoProps >= pseudoPropsSize ) {
00315                             pseudoPropsSize *= 2;
00316                 pseudoProps = (CSSOrderedProperty **)realloc( pseudoProps, pseudoPropsSize*sizeof( CSSOrderedProperty * ) );
00317             }
00318             pseudoProps[numPseudoProps++] = properties[selectorCache[i].props[p]+j];
00319             properties[selectorCache[i].props[p]+j]->pseudoId = (RenderStyle::PseudoId) selectors[i]->pseudoId;
00320             }
00321         }
00322     }
00323     else
00324         selectorCache[i].state = Invalid;
00325 
00326     }
00327 
00328 //    qDebug( "styleForElement( %s )", e->tagName().string().latin1() );
00329 //     qDebug( "%d selectors, %d checked,  %d match,  %d properties ( of %d )",
00330 //             selectors_size, schecked, smatch, (*propsToApply)->count(), properties_size );
00331 
00332     // inline style declarations, after all others. non css hints
00333     // count as author rules, and come before all other style sheets, see hack in append()
00334     if(e->m_styleDecls)
00335     numPropsToApply = addInlineDeclarations( e->m_styleDecls, numPropsToApply );
00336 
00337     bubbleSort( propsToApply, propsToApply+numPropsToApply-1 );
00338     bubbleSort( pseudoProps, pseudoProps+numPseudoProps-1 );
00339 
00340     RenderStyle *style = new RenderStyle();
00341     if( parentStyle )
00342         style->inheritFrom( parentStyle );
00343     else
00344     parentStyle = style;
00345 
00346 //    qDebug("applying properties, count=%d", numPropsToApply );
00347 
00348     // we can't apply style rules without a view() and a part. This
00349     // tends to happen on delayed destruction of widget Renderobjects
00350     if ( part ) {
00351         fontDirty = false;
00352 
00353         if (numPropsToApply ) {
00354             CSSStyleSelector::style = style;
00355             for (unsigned int i = 0; i < numPropsToApply; ++i) {
00356         if ( fontDirty && propsToApply[i]->priority >= (1 << 30) ) {
00357             // we are past the font properties, time to update to the
00358             // correct font
00359             CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics );
00360             fontDirty = false;
00361         }
00362                 applyRule( propsToApply[i]->prop );
00363         }
00364         if ( fontDirty )
00365         CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics );
00366         }
00367 
00368         if ( numPseudoProps ) {
00369         fontDirty = false;
00370             //qDebug("%d applying %d pseudo props", cssTagId, numPseudoProps);
00371             for (unsigned int i = 0; i < numPseudoProps; ++i) {
00372         if ( fontDirty && pseudoProps[i]->priority >= (1 << 30) ) {
00373             // we are past the font properties, time to update to the
00374             // correct font
00375             //We have to do this for all pseudo styles
00376             RenderStyle *pseudoStyle = style->pseudoStyle;
00377             while ( pseudoStyle ) {
00378             pseudoStyle->htmlFont().update( paintDeviceMetrics );
00379             pseudoStyle = pseudoStyle->pseudoStyle;
00380             }
00381             fontDirty = false;
00382         }
00383 
00384                 RenderStyle *pseudoStyle;
00385                 pseudoStyle = style->getPseudoStyle(pseudoProps[i]->pseudoId);
00386                 if (!pseudoStyle)
00387                 {
00388                     pseudoStyle = style->addPseudoStyle(pseudoProps[i]->pseudoId);
00389                     if (pseudoStyle)
00390                         pseudoStyle->inheritFrom( style );
00391                 }
00392 
00393         CSSStyleSelector::style = pseudoStyle;
00394                 if ( pseudoStyle )
00395                     applyRule( pseudoProps[i]->prop );
00396             }
00397 
00398         if ( fontDirty ) {
00399         RenderStyle *pseudoStyle = style->pseudoStyle;
00400         while ( pseudoStyle ) {
00401             pseudoStyle->htmlFont().update( paintDeviceMetrics );
00402             pseudoStyle = pseudoStyle->pseudoStyle;
00403         }
00404         }
00405         }
00406     }
00407 
00408     if ( usedDynamicStates & StyleSelector::Hover )
00409     style->setHasHover();
00410     if ( usedDynamicStates & StyleSelector::Active )
00411     style->setHasActive();
00412 
00413     return style;
00414 }
00415 
00416 unsigned int CSSStyleSelector::addInlineDeclarations(DOM::CSSStyleDeclarationImpl *decl,
00417                         unsigned int numProps )
00418 {
00419     QPtrList<CSSProperty> *values = decl->values();
00420     if(!values) return numProps;
00421     int len = values->count();
00422 
00423     if ( inlineProps.size() < (uint)len )
00424     inlineProps.resize( len+1 );
00425     if (numProps + len >= propsToApplySize ) {
00426         propsToApplySize += propsToApplySize;
00427         propsToApply = (CSSOrderedProperty **)realloc( propsToApply, propsToApplySize*sizeof( CSSOrderedProperty * ) );
00428     }
00429 
00430     CSSOrderedProperty *array = (CSSOrderedProperty *)inlineProps.data();
00431     for(int i = 0; i < len; i++)
00432     {
00433         CSSProperty *prop = values->at(i);
00434     Source source = Inline;
00435 
00436         if( prop->m_bImportant ) source = InlineImportant;
00437     if( prop->nonCSSHint ) source = NonCSSHint;
00438 
00439     bool first;
00440         // give special priority to font-xxx, color properties
00441         switch(prop->m_id)
00442         {
00443         case CSS_PROP_FONT_STYLE:
00444         case CSS_PROP_FONT_SIZE:
00445         case CSS_PROP_FONT_WEIGHT:
00446         case CSS_PROP_FONT_FAMILY:
00447         case CSS_PROP_FONT:
00448         case CSS_PROP_COLOR:
00449         case CSS_PROP_BACKGROUND_IMAGE:
00450         case CSS_PROP_DISPLAY:
00451             // these have to be applied first, because other properties use the computed
00452             // values of these porperties.
00453         first = true;
00454             break;
00455         default:
00456             first = false;
00457             break;
00458         }
00459 
00460     array->prop = prop;
00461     array->pseudoId = RenderStyle::NOPSEUDO;
00462     array->selector = 0;
00463     array->position = i;
00464     array->priority = (!first << 30) | (source << 24);
00465     propsToApply[numProps++] = array++;
00466     }
00467     return numProps;
00468 }
00469 
00470 static bool subject;
00471 
00472 void CSSStyleSelector::checkSelector(int selIndex, DOM::ElementImpl *e)
00473 {
00474     dynamicPseudo = RenderStyle::NOPSEUDO;
00475     selectorDynamicState = StyleSelector::None;
00476     NodeImpl *n = e;
00477 
00478     selectorCache[ selIndex ].state = Invalid;
00479     CSSSelector *sel = selectors[ selIndex ];
00480 
00481     // we have the subject part of the selector
00482     subject = true;
00483 
00484     // hack. We can't allow :hover, as it would trigger a complete
00485     // relayout with every mouse event.
00486     bool single = false;
00487     if ( sel->tag == -1 )
00488     single = true;
00489 
00490     // first selector has to match
00491     if(!checkOneSelector(sel, e)) return;
00492 
00493     // check the subselectors
00494     CSSSelector::Relation relation = sel->relation;
00495     while((sel = sel->tagHistory))
00496     {
00497         if (strictParsing || sel->tag != -1) single = false;
00498         if(!n->isElementNode()) return;
00499         switch(relation)
00500         {
00501         case CSSSelector::Descendant:
00502         {
00503             bool found = false;
00504             while(!found)
00505             {
00506         subject = false;
00507                 n = n->parentNode();
00508                 if(!n || !n->isElementNode()) return;
00509                 ElementImpl *elem = static_cast<ElementImpl *>(n);
00510                 if(checkOneSelector(sel, elem)) found = true;
00511             }
00512             break;
00513         }
00514         case CSSSelector::Child:
00515         {
00516         subject = false;
00517             n = n->parentNode();
00518             if (!strictParsing)
00519                 while (n && n->implicitNode()) n = n->parentNode();
00520             if(!n || !n->isElementNode()) return;
00521             ElementImpl *elem = static_cast<ElementImpl *>(n);
00522             if(!checkOneSelector(sel, elem)) return;
00523             break;
00524         }
00525         case CSSSelector::Sibling:
00526         {
00527         subject = false;
00528             n = n->previousSibling();
00529         while( n && !n->isElementNode() )
00530         n = n->previousSibling();
00531             if( !n ) return;
00532             ElementImpl *elem = static_cast<ElementImpl *>(n);
00533             if(!checkOneSelector(sel, elem)) return;
00534             break;
00535         }
00536         case CSSSelector::SubSelector:
00537     {
00538         //kdDebug() << "CSSOrderedRule::checkSelector" << endl;
00539         ElementImpl *elem = static_cast<ElementImpl *>(n);
00540         // a selector is invalid if something follows :first-xxx
00541         if ( dynamicPseudo != RenderStyle::NOPSEUDO ) {
00542                 qDebug("failing, dynamicPseudo: %d", dynamicPseudo);
00543         return;
00544         }
00545         if(!checkOneSelector(sel, elem)) return;
00546         //kdDebug() << "CSSOrderedRule::checkSelector: passed" << endl;
00547         break;
00548     }
00549         }
00550         relation = sel->relation;
00551     }
00552     // disallow *:hover
00553     if ( single && selectorDynamicState & StyleSelector::Hover )
00554     return;
00555     usedDynamicStates |= selectorDynamicState;
00556     if ((selectorDynamicState & dynamicState) != selectorDynamicState)
00557     return;
00558     if ( dynamicPseudo != RenderStyle::NOPSEUDO ) {
00559     selectorCache[selIndex].state = AppliesPseudo;
00560     selectors[ selIndex ]->pseudoId = dynamicPseudo;
00561     } else
00562     selectorCache[ selIndex ].state = Applies;
00563 //     qDebug( "selector %d applies", selIndex );
00564 //     selectors[ selIndex ]->print();
00565     return;
00566 }
00567 
00568 // modified version of the one in kurl.cpp
00569 static void cleanpath(QString &path)
00570 {
00571     int pos;
00572     while ( (pos = path.find( "/../" )) != -1 ) {
00573     int prev = 0;
00574     if ( pos > 0 )
00575         prev = path.findRev( "/", pos -1 );
00576         // don't remove the host, i.e. http://foo.org/../foo.html
00577         if (prev < 0 || (prev > 3 && path.findRev("://", prev-1) == prev-2))
00578             path.remove( pos, 3);
00579         else
00580             // matching directory found ?
00581             path.remove( prev, pos- prev + 3 );
00582     }
00583     pos = 0;
00584     while ( (pos = path.find( "//", pos )) != -1) {
00585     if ( pos == 0 || path[pos-1] != ':' )
00586         path.remove( pos, 1 );
00587     else
00588         pos += 2;
00589     }
00590     while ( (pos = path.find( "/./" )) != -1)
00591     path.remove( pos, 2 );
00592     //kdDebug() << "checkPseudoState " << path << endl;
00593 }
00594 
00595 static void checkPseudoState( const CSSStyleSelector::Encodedurl& encodedurl, DOM::ElementImpl *e )
00596 {
00597     DOMString attr;
00598     if( e->id() != ID_A || (attr = e->getAttribute(ATTR_HREF)).isNull() ) {
00599     pseudoState = PseudoNone;
00600     return;
00601     }
00602     QString u = attr.string();
00603     if ( u.find("://") == -1 ) {
00604     if ( u[0] == '/' )
00605         u = encodedurl.host + u;
00606     else if ( u[0] == '#' )
00607         u = encodedurl.file + u;
00608     else
00609         u = encodedurl.path + u;
00610     cleanpath( u );
00611     }
00612     //completeURL( attr.string() );
00613     pseudoState = KHTMLFactory::vLinks()->contains( u ) ? PseudoVisited : PseudoLink;
00614 }
00615 
00616 bool CSSStyleSelector::checkOneSelector(DOM::CSSSelector *sel, DOM::ElementImpl *e)
00617 {
00618     if(!e)
00619         return false;
00620 
00621 //     qDebug("element: %d", e->id());
00622 //     sel->print();
00623 
00624 
00625     if((e->id() & NodeImpl_IdLocalMask) != uint(sel->tag) && sel->tag != -1) return false;
00626 
00627     if(sel->attr)
00628     {
00629         DOMString value = e->getAttribute(sel->attr);
00630         if(value.isNull()) return false; // attribute is not set
00631 
00632         switch(sel->match)
00633         {
00634         case CSSSelector::Exact:
00635         if( (strictParsing && strcmp(sel->value, value) ) ||
00636                 (!strictParsing && strcasecmp(sel->value, value)))
00637                 return false;
00638             break;
00639         case CSSSelector::Set:
00640             break;
00641         case CSSSelector::List:
00642         {
00643         int l = value.implementation()->l;
00644         int sl = sel->value.implementation()->l;
00645             QConstString str( value.implementation()->s, l );
00646             QConstString selStr( sel->value.implementation()->s, sl );
00647             int pos = str.string().find(selStr.string(), 0, strictParsing);
00648             if(pos == -1) return false;
00649             if(pos && value.implementation()->s[pos-1] != ' ') return false;
00650             pos += selStr.string().length();
00651             if(pos < l && value.implementation()->s[pos] != ' ') return false;
00652             break;
00653         }
00654         case CSSSelector::Contain:
00655         {
00656             //kdDebug( 6080 ) << "checking for contains match" << endl;
00657         int l = value.implementation()->l;
00658         int sl = sel->value.implementation()->l;
00659             QConstString str( value.implementation()->s, l );
00660             QConstString selStr( sel->value.implementation()->s, sl );
00661             int pos = str.string().find(selStr.string(), 0, strictParsing);
00662             if(pos == -1) return false;
00663             break;
00664         }
00665         case CSSSelector::Begin:
00666         {
00667             //kdDebug( 6080 ) << "checking for beginswith match" << endl;
00668         int l = value.implementation()->l;
00669         int sl = sel->value.implementation()->l;
00670             QConstString str( value.implementation()->s, l );
00671             QConstString selStr( sel->value.implementation()->s, sl );
00672             int pos = str.string().find(selStr.string(), 0, strictParsing);
00673             if(pos != 0) return false;
00674             break;
00675         }
00676         case CSSSelector::End:
00677         {
00678             //kdDebug( 6080 ) << "checking for endswith match" << endl;
00679         int l = value.implementation()->l;
00680         int sl = sel->value.implementation()->l;
00681             QConstString str( value.implementation()->s, l );
00682             QConstString selStr( sel->value.implementation()->s, sl );
00683         if (strictParsing && !str.string().endsWith(selStr.string())) return false;
00684         if (!strictParsing) {
00685             int pos = l - sl;
00686         if (pos < 0 || pos != str.string().find(selStr.string(), pos, false) )
00687             return false;
00688         }
00689             break;
00690         }
00691         case CSSSelector::Hyphen:
00692         {
00693             //kdDebug( 6080 ) << "checking for hyphen match" << endl;
00694         int l = value.implementation()->l;
00695         int sl = sel->value.implementation()->l;
00696             QConstString str( value.implementation()->s, l );
00697             QConstString selStr( sel->value.implementation()->s, sl );
00698             if(str.string().length() < selStr.string().length()) return false;
00699             // Check if str begins with selStr:
00700             if(str.string().find(selStr.string(), 0, strictParsing) != 0) return false;
00701             // It does. Check for exact match or following '-':
00702             if(l != sl
00703                 && value.implementation()->s[sl] != '-') return false;
00704             break;
00705         }
00706         case CSSSelector::Pseudo:
00707         case CSSSelector::None:
00708             break;
00709         }
00710     }
00711     if(sel->match == CSSSelector::Pseudo)
00712     {
00713         // Pseudo elements. We need to check first child here. No dynamic pseudo
00714         // elements for the moment
00715     QConstString cstr( sel->value.implementation()->s, sel->value.implementation()->l );
00716     const QString& value = cstr.string();
00717 //  kdDebug() << "CSSOrderedRule::pseudo " << value << endl;
00718     switch( *( value.unicode() ) ) {
00719     case 'f':
00720         if(value == "first-child") {
00721         // first-child matches the first child that is an element!
00722         DOM::NodeImpl *n = e->parentNode()->firstChild();
00723         while( n && !n->isElementNode() )
00724             n = n->nextSibling();
00725         if( n == e )
00726             return true;
00727         } else if ( value == "first-line" && subject) {
00728                 dynamicPseudo=RenderStyle::FIRST_LINE;
00729                 return true;
00730         } else if ( value == "first-letter" && subject ) {
00731         dynamicPseudo=RenderStyle::FIRST_LETTER;
00732         return true;
00733         } else if ( value == "focus" ) {
00734         selectorDynamicState |= StyleSelector::Focus;
00735         return true;
00736         }
00737         break;
00738     case 'l':
00739         if( value == "link") {
00740         if ( pseudoState == PseudoUnknown )
00741             checkPseudoState( encodedurl, e );
00742         if ( pseudoState == PseudoLink ) {
00743             return true;
00744         }
00745         }
00746         break;
00747     case 'v':
00748         if ( value == "visited" ) {
00749         if ( pseudoState == PseudoUnknown )
00750             checkPseudoState( encodedurl, e );
00751         if ( pseudoState == PseudoVisited )
00752             return true;
00753         }
00754         break;
00755     case 'h':
00756         if ( value == "hover" ) {
00757         selectorDynamicState |= StyleSelector::Hover;
00758         // dynamic pseudos have to be sorted out in checkSelector, so we if it could in some state apply
00759         // to the element.
00760         return true;
00761         } break;
00762     case 'a':
00763         if ( value == "active" ) {
00764         if ( pseudoState == PseudoUnknown )
00765             checkPseudoState( encodedurl, e );
00766         if ( pseudoState != PseudoNone ) {
00767             selectorDynamicState |= StyleSelector::Active;
00768             return true;
00769         }
00770         } else if ( value == "after" ) {
00771         dynamicPseudo = RenderStyle::AFTER;
00772         return true;
00773         }
00774 
00775         break;
00776     case 'b':
00777         if ( value == "before" ) {
00778         dynamicPseudo = RenderStyle::BEFORE;
00779         return true;
00780         }
00781         break;
00782     default:
00783         return false;
00784     }
00785     return false;
00786     }
00787     // ### add the rest of the checks...
00788     return true;
00789 }
00790 
00791 void CSSStyleSelector::clearLists()
00792 {
00793     if ( selectors ) delete [] selectors;
00794     if ( selectorCache ) {
00795         for ( unsigned int i = 0; i < selectors_size; i++ )
00796             if ( selectorCache[i].props )
00797                 delete [] selectorCache[i].props;
00798 
00799         delete [] selectorCache;
00800     }
00801     if ( properties ) {
00802     CSSOrderedProperty **prop = properties;
00803     while ( *prop ) {
00804         delete (*prop);
00805         prop++;
00806     }
00807         delete [] properties;
00808     }
00809     selectors = 0;
00810     properties = 0;
00811     selectorCache = 0;
00812 }
00813 
00814 
00815 void CSSStyleSelector::buildLists()
00816 {
00817     clearLists();
00818     // collect all selectors and Properties in lists. Then transer them to the array for faster lookup.
00819 
00820     QPtrList<CSSSelector> selectorList;
00821     CSSOrderedPropertyList propertyList;
00822 
00823     if(m_medium == "print" && defaultPrintStyle)
00824       defaultPrintStyle->collect( &selectorList, &propertyList, Default,
00825         Default );
00826     else if(defaultStyle) defaultStyle->collect( &selectorList, &propertyList,
00827       Default, Default );
00828     if(userStyle) userStyle->collect(&selectorList, &propertyList, User, UserImportant );
00829     if(authorStyle) authorStyle->collect(&selectorList, &propertyList, Author, AuthorImportant );
00830 
00831     selectors_size = selectorList.count();
00832     selectors = new CSSSelector *[selectors_size];
00833     CSSSelector *s = selectorList.first();
00834     CSSSelector **sel = selectors;
00835     while ( s ) {
00836     *sel = s;
00837     s = selectorList.next();
00838     ++sel;
00839     }
00840 
00841     selectorCache = new SelectorCache[selectors_size];
00842     for ( unsigned int i = 0; i < selectors_size; i++ ) {
00843         selectorCache[i].state = Unknown;
00844         selectorCache[i].props_size = 0;
00845         selectorCache[i].props = 0;
00846     }
00847 
00848     // presort properties. Should make the sort() calls in styleForElement faster.
00849     propertyList.sort();
00850     properties_size = propertyList.count() + 1;
00851     properties = new CSSOrderedProperty *[ properties_size ];
00852     CSSOrderedProperty *p = propertyList.first();
00853     CSSOrderedProperty **prop = properties;
00854     while ( p ) {
00855     *prop = p;
00856     p = propertyList.next();
00857     ++prop;
00858     }
00859     *prop = 0;
00860 
00861     unsigned int* offsets = new unsigned int[selectors_size];
00862     if(properties[0])
00863     offsets[properties[0]->selector] = 0;
00864     for(unsigned int p = 1; p < properties_size; ++p) {
00865 
00866     if(!properties[p] || (properties[p]->selector != properties[p - 1]->selector)) {
00867         unsigned int sel = properties[p - 1]->selector;
00868             int* newprops = new int[selectorCache[sel].props_size+2];
00869             for ( unsigned int i=0; i < selectorCache[sel].props_size; i++ )
00870                 newprops[i] = selectorCache[sel].props[i];
00871 
00872         newprops[selectorCache[sel].props_size] = offsets[sel];
00873         newprops[selectorCache[sel].props_size+1] = p - offsets[sel];
00874             delete [] selectorCache[sel].props;
00875             selectorCache[sel].props = newprops;
00876             selectorCache[sel].props_size += 2;
00877 
00878         if(properties[p]) {
00879         sel = properties[p]->selector;
00880         offsets[sel] = p;
00881             }
00882         }
00883     }
00884     delete [] offsets;
00885 
00886 
00887 #if 0
00888     // and now the same for the selector map
00889     for ( unsigned int sel = 0; sel < selectors_size; ++sel ) {
00890         kdDebug( 6080 ) << "trying for sel: " << sel << endl;
00891         int len = 0;
00892         int offset = 0;
00893         bool matches = false;
00894         for ( unsigned int i = 0; i < selectors_size; i++ ) {
00895             int tag = selectors[i]->tag;
00896             if ( sel != tag && tag != -1 )
00897                 selectorCache[i].state = Invalid;
00898             else
00899                 selectorCache[i].state = Unknown;
00900 
00901             if ( matches != ( selectorCache[i].state == Unknown ) ) {
00902                 if ( matches ) {
00903                     kdDebug( 6080 ) << "new: offs: " << offset << " len: " << len << endl;
00904                     matches = false;
00905                 }
00906                 else {
00907                     matches = true;
00908 //                    offset = p-selectors;
00909                     len = 0;
00910                 }
00911             }
00912             ++len;
00913         }
00914     }
00915 #endif
00916 }
00917 
00918 
00919 // ----------------------------------------------------------------------
00920 
00921 
00922 CSSOrderedRule::CSSOrderedRule(DOM::CSSStyleRuleImpl *r, DOM::CSSSelector *s, int _index)
00923 {
00924     rule = r;
00925     if(rule) r->ref();
00926     index = _index;
00927     selector = s;
00928 }
00929 
00930 CSSOrderedRule::~CSSOrderedRule()
00931 {
00932     if(rule) rule->deref();
00933 }
00934 
00935 // -----------------------------------------------------------------
00936 
00937 CSSStyleSelectorList::CSSStyleSelectorList()
00938     : QPtrList<CSSOrderedRule>()
00939 {
00940     setAutoDelete(true);
00941 }
00942 CSSStyleSelectorList::~CSSStyleSelectorList()
00943 {
00944 }
00945 
00946 void CSSStyleSelectorList::append( CSSStyleSheetImpl *sheet,
00947                                    const DOMString &medium )
00948 {
00949     if(!sheet || !sheet->isCSSStyleSheet()) return;
00950 
00951     // No media implies "all", but if a medialist exists it must
00952     // contain our current medium
00953     if( sheet->media() && !sheet->media()->contains( medium ) )
00954         return; // style sheet not applicable for this medium
00955 
00956     int len = sheet->length();
00957 
00958     for(int i = 0; i< len; i++)
00959     {
00960         StyleBaseImpl *item = sheet->item(i);
00961         if(item->isStyleRule())
00962         {
00963             CSSStyleRuleImpl *r = static_cast<CSSStyleRuleImpl *>(item);
00964             QPtrList<CSSSelector> *s = r->selector();
00965             for(int j = 0; j < (int)s->count(); j++)
00966             {
00967                 CSSOrderedRule *rule = new CSSOrderedRule(r, s->at(j), count());
00968         QPtrList<CSSOrderedRule>::append(rule);
00969                 //kdDebug( 6080 ) << "appending StyleRule!" << endl;
00970             }
00971         }
00972         else if(item->isImportRule())
00973         {
00974             CSSImportRuleImpl *import = static_cast<CSSImportRuleImpl *>(item);
00975 
00976             //kdDebug( 6080 ) << "@import: Media: "
00977             //                << import->media()->mediaText().string() << endl;
00978 
00979             if( !import->media() || import->media()->contains( medium ) )
00980             {
00981                 CSSStyleSheetImpl *importedSheet = import->styleSheet();
00982                 append( importedSheet, medium );
00983             }
00984         }
00985         else if( item->isMediaRule() )
00986         {
00987             CSSMediaRuleImpl *r = static_cast<CSSMediaRuleImpl *>( item );
00988             CSSRuleListImpl *rules = r->cssRules();
00989 
00990             //DOMString mediaText = media->mediaText();
00991             //kdDebug( 6080 ) << "@media: Media: "
00992             //                << r->media()->mediaText().string() << endl;
00993 
00994             if( ( !r->media() || r->media()->contains( medium ) ) && rules)
00995             {
00996                 // Traverse child elements of the @import rule. Since
00997                 // many elements are not allowed as child we do not use
00998                 // a recursive call to append() here
00999                 for( unsigned j = 0; j < rules->length(); j++ )
01000                 {
01001                     //kdDebug( 6080 ) << "*** Rule #" << j << endl;
01002 
01003                     CSSRuleImpl *childItem = rules->item( j );
01004                     if( childItem->isStyleRule() )
01005                     {
01006                         // It is a StyleRule, so append it to our list
01007                         CSSStyleRuleImpl *styleRule =
01008                                 static_cast<CSSStyleRuleImpl *>( childItem );
01009 
01010                         QPtrList<CSSSelector> *s = styleRule->selector();
01011                         for( int j = 0; j < ( int ) s->count(); j++ )
01012                         {
01013                             CSSOrderedRule *orderedRule = new CSSOrderedRule(
01014                                             styleRule, s->at( j ), count() );
01015                         QPtrList<CSSOrderedRule>::append( orderedRule );
01016                         }
01017                     }
01018                     else
01019                     {
01020                         //kdDebug( 6080 ) << "Ignoring child rule of "
01021                         //    "ImportRule: rule is not a StyleRule!" << endl;
01022                     }
01023                 }   // for rules
01024             }   // if rules
01025             else
01026             {
01027                 //kdDebug( 6080 ) << "CSSMediaRule not rendered: "
01028                 //                << "rule empty or wrong medium!" << endl;
01029             }
01030         }
01031         // ### include other rules
01032     }
01033 }
01034 
01035 
01036 void CSSStyleSelectorList::collect( QPtrList<CSSSelector> *selectorList, CSSOrderedPropertyList *propList,
01037                     Source regular, Source important )
01038 {
01039     CSSOrderedRule *r = first();
01040     while( r ) {
01041     CSSSelector *sel = selectorList->first();
01042     int selectorNum = 0;
01043     while( sel ) {
01044         if ( *sel == *(r->selector) )
01045         break;
01046         sel = selectorList->next();
01047         selectorNum++;
01048     }
01049     if ( !sel )
01050         selectorList->append( r->selector );
01051 //  else
01052 //      qDebug("merged one selector");
01053     propList->append(r->rule->declaration(), selectorNum, r->selector->specificity(), regular, important );
01054     r = next();
01055     }
01056 }
01057 
01058 // -------------------------------------------------------------------------
01059 
01060 int CSSOrderedPropertyList::compareItems(QPtrCollection::Item i1, QPtrCollection::Item i2)
01061 {
01062     int diff =  static_cast<CSSOrderedProperty *>(i1)->priority
01063         - static_cast<CSSOrderedProperty *>(i2)->priority;
01064     return diff ? diff : static_cast<CSSOrderedProperty *>(i1)->position
01065         - static_cast<CSSOrderedProperty *>(i2)->position;
01066 }
01067 
01068 void CSSOrderedPropertyList::append(DOM::CSSStyleDeclarationImpl *decl, uint selector, uint specificity,
01069                     Source regular, Source important )
01070 {
01071     QPtrList<CSSProperty> *values = decl->values();
01072     if(!values) return;
01073     int len = values->count();
01074     for(int i = 0; i < len; i++)
01075     {
01076         CSSProperty *prop = values->at(i);
01077     Source source = regular;
01078 
01079     if( prop->m_bImportant ) source = important;
01080     if( prop->nonCSSHint ) source = NonCSSHint;
01081 
01082     bool first = false;
01083         // give special priority to font-xxx, color properties
01084         switch(prop->m_id)
01085         {
01086     case CSS_PROP_FONT_STYLE:
01087         case CSS_PROP_FONT_SIZE:
01088     case CSS_PROP_FONT_WEIGHT:
01089     case CSS_PROP_FONT_FAMILY:
01090         case CSS_PROP_FONT:
01091         case CSS_PROP_COLOR:
01092         case CSS_PROP_BACKGROUND_IMAGE:
01093         case CSS_PROP_DISPLAY:
01094             // these have to be applied first, because other properties use the computed
01095             // values of these porperties.
01096         first = true;
01097             break;
01098         default:
01099             break;
01100         }
01101 
01102     QPtrList<CSSOrderedProperty>::append(new CSSOrderedProperty(prop, selector,
01103                                  first, source, specificity,
01104                                  count() ));
01105     }
01106 }
01107 
01108 // -------------------------------------------------------------------------------------
01109 // this is mostly boring stuff on how to apply a certain rule to the renderstyle...
01110 
01111 static Length convertToLength( CSSPrimitiveValueImpl *primitiveValue, RenderStyle *style, QPaintDeviceMetrics *paintDeviceMetrics, bool *ok = 0 )
01112 {
01113     Length l;
01114     if ( !primitiveValue ) {
01115     if ( ok )
01116         *ok = false;
01117     } else {
01118     int type = primitiveValue->primitiveType();
01119     if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
01120         l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
01121     else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
01122         l = Length(int(primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE)), Percent);
01123     else if(type == CSSPrimitiveValue::CSS_NUMBER)
01124         l = Length(int(primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_NUMBER)*100), Percent);
01125     else if (type == CSSPrimitiveValue::CSS_HTML_RELATIVE)
01126         l = Length(int(primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_HTML_RELATIVE)), Relative);
01127     else if ( ok )
01128         *ok = false;
01129     }
01130     return l;
01131 }
01132 
01133 void CSSStyleSelector::applyRule( DOM::CSSProperty *prop )
01134 {
01135     CSSValueImpl *value = prop->value();
01136 
01137     //kdDebug( 6080 ) << "applying property " << prop->m_id << endl;
01138 
01139     CSSPrimitiveValueImpl *primitiveValue = 0;
01140     if(value->isPrimitiveValue()) primitiveValue = static_cast<CSSPrimitiveValueImpl *>(value);
01141 
01142     Length l;
01143     bool apply = false;
01144 
01145     // here follows a long list, defining how to aplly certain properties to the style object.
01146     // rather boring stuff...
01147     switch(prop->m_id)
01148     {
01149 // ident only properties
01150     case CSS_PROP_BACKGROUND_ATTACHMENT:
01151         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01152         {
01153             if( !parentNode ) return;
01154             style->setBackgroundAttachment(parentStyle->backgroundAttachment());
01155             return;
01156         }
01157         if(!primitiveValue) break;
01158         switch(primitiveValue->getIdent())
01159         {
01160         case CSS_VAL_FIXED:
01161             {
01162                 style->setBackgroundAttachment(false);
01163         // only use slow repaints if we actually have a background pixmap
01164                 if( style->backgroundImage() )
01165                     view->useSlowRepaints();
01166                 break;
01167             }
01168         case CSS_VAL_SCROLL:
01169             style->setBackgroundAttachment(true);
01170             break;
01171         default:
01172             return;
01173         }
01174     case CSS_PROP_BACKGROUND_REPEAT:
01175     {
01176         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01177             if(!parentNode) return;
01178             style->setBackgroundRepeat(parentStyle->backgroundRepeat());
01179             return;
01180         }
01181         if(!primitiveValue) return;
01182     switch(primitiveValue->getIdent())
01183     {
01184     case CSS_VAL_REPEAT:
01185         style->setBackgroundRepeat( REPEAT );
01186         break;
01187     case CSS_VAL_REPEAT_X:
01188         style->setBackgroundRepeat( REPEAT_X );
01189         break;
01190     case CSS_VAL_REPEAT_Y:
01191         style->setBackgroundRepeat( REPEAT_Y );
01192         break;
01193     case CSS_VAL_NO_REPEAT:
01194         style->setBackgroundRepeat( NO_REPEAT );
01195         break;
01196     default:
01197         return;
01198     }
01199     }
01200     case CSS_PROP_BORDER_COLLAPSE:
01201         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01202         {
01203             if(!parentNode) return;
01204             style->setBorderCollapse(parentStyle->borderCollapse());
01205             break;
01206         }
01207         if(!primitiveValue) break;
01208         switch(primitiveValue->getIdent())
01209         {
01210         case CSS_VAL_COLLAPSE:
01211             style->setBorderCollapse(true);
01212             break;
01213         case CSS_VAL_SCROLL:
01214             style->setBorderCollapse(false);
01215             break;
01216         default:
01217             return;
01218         }
01219 
01220     case CSS_PROP_BORDER_TOP_STYLE:
01221     case CSS_PROP_BORDER_RIGHT_STYLE:
01222     case CSS_PROP_BORDER_BOTTOM_STYLE:
01223     case CSS_PROP_BORDER_LEFT_STYLE:
01224     case CSS_PROP_OUTLINE_STYLE:
01225     {
01226     EBorderStyle s;
01227         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01228         {
01229             if(!parentNode) return;
01230             switch(prop->m_id)
01231             {
01232             case CSS_PROP_BORDER_TOP_STYLE:
01233                 s = parentStyle->borderTopStyle();
01234                 break;
01235             case CSS_PROP_BORDER_RIGHT_STYLE:
01236                 s = parentStyle->borderRightStyle();
01237                 break;
01238             case CSS_PROP_BORDER_BOTTOM_STYLE:
01239                 s = parentStyle->borderBottomStyle();
01240                 break;
01241             case CSS_PROP_BORDER_LEFT_STYLE:
01242                 s = parentStyle->borderLeftStyle();
01243                 break;
01244             case CSS_PROP_OUTLINE_STYLE:
01245                 s = parentStyle->outlineStyle();
01246                 break;
01247         default:
01248                 return;
01249         }
01250         } else {
01251         if(!primitiveValue) return;
01252         s = (EBorderStyle) (primitiveValue->getIdent() - CSS_VAL_NONE);
01253     }
01254         switch(prop->m_id)
01255         {
01256         case CSS_PROP_BORDER_TOP_STYLE:
01257             style->setBorderTopStyle(s); return;
01258         case CSS_PROP_BORDER_RIGHT_STYLE:
01259             style->setBorderRightStyle(s); return;
01260         case CSS_PROP_BORDER_BOTTOM_STYLE:
01261             style->setBorderBottomStyle(s); return;
01262         case CSS_PROP_BORDER_LEFT_STYLE:
01263             style->setBorderLeftStyle(s); return;
01264         case CSS_PROP_OUTLINE_STYLE:
01265             style->setOutlineStyle(s); return;
01266         default:
01267             return;
01268         }
01269         return;
01270     }
01271     case CSS_PROP_CAPTION_SIDE:
01272     {
01273         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01274         {
01275             if(!parentNode) return;
01276             style->setCaptionSide(parentStyle->captionSide());
01277             break;
01278         }
01279         if(!primitiveValue) break;
01280         ECaptionSide c = CAPTOP;
01281         switch(primitiveValue->getIdent())
01282         {
01283         case CSS_VAL_TOP:
01284             c = CAPTOP; break;
01285         case CSS_VAL_BOTTOM:
01286             c = CAPBOTTOM; break;
01287         default:
01288             return;
01289         }
01290         style->setCaptionSide(c);
01291         return;
01292     }
01293     case CSS_PROP_CLEAR:
01294     {
01295         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01296         {
01297             if(!parentNode) return;
01298             style->setClear(parentStyle->clear());
01299             break;
01300         }
01301         if(!primitiveValue) break;
01302         EClear c = CNONE;
01303         switch(primitiveValue->getIdent())
01304         {
01305         case CSS_VAL_LEFT:
01306             c = CLEFT; break;
01307         case CSS_VAL_RIGHT:
01308             c = CRIGHT; break;
01309         case CSS_VAL_BOTH:
01310             c = CBOTH; break;
01311         default:
01312             return;
01313         }
01314         style->setClear(c);
01315         return;
01316     }
01317     case CSS_PROP_DIRECTION:
01318     {
01319         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01320         {
01321             if(!parentNode) return;
01322             style->setDirection(parentStyle->direction());
01323             break;
01324         }
01325         if(!primitiveValue) break;
01326         style->setDirection( (EDirection) (primitiveValue->getIdent() - CSS_VAL_LTR) );
01327         return;
01328     }
01329     case CSS_PROP_DISPLAY:
01330     {
01331         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01332         {
01333             if(!parentNode) return;
01334             style->setDisplay(parentStyle->display());
01335             break;
01336         }
01337         if(!primitiveValue) break;
01338     int id = primitiveValue->getIdent();
01339     EDisplay d;
01340     if ( id == CSS_VAL_NONE) {
01341         d = NONE;
01342     } else if ( id == CSS_VAL_RUN_IN || id == CSS_VAL_INLINE_BLOCK ) {
01343         // these are not supported at the moment, so we just ignore them.
01344         return;
01345     } else {
01346         d = EDisplay(primitiveValue->getIdent() - CSS_VAL_INLINE);
01347     }
01348 
01349         style->setDisplay(d);
01350         //kdDebug( 6080 ) << "setting display to " << d << endl;
01351 
01352         break;
01353     }
01354 
01355     case CSS_PROP_EMPTY_CELLS:
01356         break;
01357     case CSS_PROP_FLOAT:
01358     {
01359         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01360         {
01361             if(!parentNode) return;
01362             style->setFloating(parentStyle->floating());
01363             return;
01364         }
01365         if(!primitiveValue) return;
01366         EFloat f;
01367         switch(primitiveValue->getIdent())
01368         {
01369         case CSS_VAL_LEFT:
01370             f = FLEFT; break;
01371         case CSS_VAL_RIGHT:
01372             f = FRIGHT; break;
01373         case CSS_VAL_NONE:
01374         case CSS_VAL_CENTER:  //Non standart CSS-Value
01375             f = FNONE; break;
01376         default:
01377             return;
01378         }
01379         if (f!=FNONE && style->display()==LIST_ITEM)
01380             style->setDisplay(BLOCK);
01381 
01382         style->setFloating(f);
01383         break;
01384     }
01385 
01386         break;
01387     case CSS_PROP_FONT_STYLE:
01388     {
01389         FontDef fontDef = style->htmlFont().fontDef;
01390         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01391             if(!parentNode) return;
01392             fontDef.italic = parentStyle->htmlFont().fontDef.italic;
01393     } else {
01394         if(!primitiveValue) return;
01395         switch(primitiveValue->getIdent()) {
01396         case CSS_VAL_OBLIQUE:
01397         // ### oblique is the same as italic for the moment...
01398         case CSS_VAL_ITALIC:
01399             fontDef.italic = true;
01400             break;
01401         case CSS_VAL_NORMAL:
01402             fontDef.italic = false;
01403             break;
01404         default:
01405             return;
01406         }
01407     }
01408         if (style->setFontDef( fontDef ))
01409     fontDirty = true;
01410         break;
01411     }
01412 
01413 
01414     case CSS_PROP_FONT_VARIANT:
01415     {
01416         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01417             if(!parentNode) return;
01418             style->setFontVariant(parentStyle->fontVariant());
01419             return;
01420         }
01421         if(!primitiveValue) return;
01422         switch(primitiveValue->getIdent()) {
01423         case CSS_VAL_NORMAL:
01424         style->setFontVariant( FVNORMAL ); break;
01425         case CSS_VAL_SMALL_CAPS:
01426         style->setFontVariant( SMALL_CAPS ); break;
01427         default:
01428             return;
01429         }
01430     break;
01431     }
01432 
01433     case CSS_PROP_FONT_WEIGHT:
01434     {
01435         FontDef fontDef = style->htmlFont().fontDef;
01436         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01437             if(!parentNode) return;
01438             fontDef.weight = parentStyle->htmlFont().fontDef.weight;
01439         } else {
01440         if(!primitiveValue) return;
01441         if(primitiveValue->getIdent())
01442         {
01443         switch(primitiveValue->getIdent())
01444         {
01445             // ### we just support normal and bold fonts at the moment...
01446             // setWeight can actually accept values between 0 and 99...
01447             case CSS_VAL_BOLD:
01448             case CSS_VAL_BOLDER:
01449             fontDef.weight = QFont::Bold;
01450             break;
01451             case CSS_VAL_NORMAL:
01452             case CSS_VAL_LIGHTER:
01453             fontDef.weight = QFont::Normal;
01454             break;
01455             default:
01456             return;
01457         }
01458         }
01459         else
01460         {
01461         // ### fix parsing of 100-900 values in parser, apply them here
01462         }
01463     }
01464         if (style->setFontDef( fontDef ))
01465     fontDirty = true;
01466         break;
01467     }
01468 
01469     case CSS_PROP_LIST_STYLE_POSITION:
01470     {
01471         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01472         {
01473             if(!parentNode) return;
01474             style->setListStylePosition(parentStyle->listStylePosition());
01475             return;
01476         }
01477         if(!primitiveValue) return;
01478         if(primitiveValue->getIdent())
01479             style->setListStylePosition( (EListStylePosition) (primitiveValue->getIdent() - CSS_VAL_OUTSIDE) );
01480         return;
01481     }
01482 
01483     case CSS_PROP_LIST_STYLE_TYPE:
01484     {
01485         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01486         {
01487             if(!parentNode) return;
01488             style->setListStyleType(parentStyle->listStyleType());
01489             return;
01490         }
01491         if(!primitiveValue) return;
01492         if(primitiveValue->getIdent())
01493         {
01494             EListStyleType t;
01495         int id = primitiveValue->getIdent();
01496         if ( id == CSS_VAL_NONE) { // important!!
01497           t = LNONE;
01498         } else {
01499           t = EListStyleType(id - CSS_VAL_DISC);
01500         }
01501             style->setListStyleType(t);
01502         }
01503         return;
01504     }
01505 
01506     case CSS_PROP_OVERFLOW:
01507     {
01508         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01509         {
01510             if(!parentNode) return;
01511             style->setOverflow(parentStyle->overflow());
01512             return;
01513         }
01514         if(!primitiveValue) return;
01515         EOverflow o;
01516         switch(primitiveValue->getIdent())
01517         {
01518         case CSS_VAL_VISIBLE:
01519             o = OVISIBLE; break;
01520         case CSS_VAL_HIDDEN:
01521             o = OHIDDEN; break;
01522         case CSS_VAL_SCROLL:
01523             o = SCROLL; break;
01524         case CSS_VAL_AUTO:
01525             o = AUTO; break;
01526         default:
01527             return;
01528         }
01529         style->setOverflow(o);
01530         return;
01531     }
01532     break;
01533     case CSS_PROP_PAGE:
01534     case CSS_PROP_PAGE_BREAK_AFTER:
01535     case CSS_PROP_PAGE_BREAK_BEFORE:
01536     case CSS_PROP_PAGE_BREAK_INSIDE:
01537 //    case CSS_PROP_PAUSE_AFTER:
01538 //    case CSS_PROP_PAUSE_BEFORE:
01539         break;
01540 
01541     case CSS_PROP_POSITION:
01542     {
01543         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01544         {
01545             if(!parentNode) return;
01546             style->setPosition(parentStyle->position());
01547             return;
01548         }
01549         if(!primitiveValue) return;
01550         EPosition p;
01551         switch(primitiveValue->getIdent())
01552         {
01553         case CSS_VAL_STATIC:
01554             p = STATIC; break;
01555         case CSS_VAL_RELATIVE:
01556             p = RELATIVE; break;
01557         case CSS_VAL_ABSOLUTE:
01558             p = ABSOLUTE; break;
01559         case CSS_VAL_FIXED:
01560             {
01561                 view->useSlowRepaints();
01562                 p = FIXED;
01563                 break;
01564             }
01565         default:
01566             return;
01567         }
01568         style->setPosition(p);
01569         return;
01570     }
01571 
01572 //     case CSS_PROP_SPEAK:
01573 //     case CSS_PROP_SPEAK_HEADER:
01574 //     case CSS_PROP_SPEAK_NUMERAL:
01575 //     case CSS_PROP_SPEAK_PUNCTUATION:
01576     case CSS_PROP_TABLE_LAYOUT: {
01577     if ( !primitiveValue->getIdent() )
01578         return;
01579 
01580     ETableLayout l = TAUTO;
01581     switch( primitiveValue->getIdent() ) {
01582     case CSS_VAL_FIXED:
01583         l = TFIXED;
01584         // fall through
01585     case CSS_VAL_AUTO:
01586         style->setTableLayout( l );
01587     default:
01588         break;
01589     }
01590     break;
01591     }
01592     case CSS_PROP_UNICODE_BIDI: {
01593     EUnicodeBidi b = UBNormal;
01594         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01595             if(!parentNode) return;
01596             b = parentStyle->unicodeBidi();
01597         } else {
01598         switch( primitiveValue->getIdent() ) {
01599         case CSS_VAL_NORMAL:
01600             b = UBNormal; break;
01601         case CSS_VAL_EMBED:
01602             b = Embed; break;
01603         case CSS_VAL_BIDI_OVERRIDE:
01604             b = Override; break;
01605         default:
01606             return;
01607         }
01608     }
01609     style->setUnicodeBidi( b );
01610         break;
01611     }
01612     case CSS_PROP_TEXT_TRANSFORM:
01613         {
01614         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01615             if(!parentNode) return;
01616             style->setTextTransform(parentStyle->textTransform());
01617             return;
01618         }
01619 
01620         if(!primitiveValue->getIdent()) return;
01621 
01622         ETextTransform tt;
01623         switch(primitiveValue->getIdent()) {
01624         case CSS_VAL_CAPITALIZE:  tt = CAPITALIZE;  break;
01625         case CSS_VAL_UPPERCASE:   tt = UPPERCASE;   break;
01626         case CSS_VAL_LOWERCASE:   tt = LOWERCASE;   break;
01627         case CSS_VAL_NONE:
01628         default:                  tt = TTNONE;      break;
01629         }
01630         style->setTextTransform(tt);
01631         break;
01632         }
01633 
01634     case CSS_PROP_VISIBILITY:
01635     {
01636         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01637             if(!parentNode) return;
01638             style->setVisibility(parentStyle->visibility());
01639             return;
01640         }
01641 
01642         switch( primitiveValue->getIdent() ) {
01643         case CSS_VAL_HIDDEN:
01644             style->setVisibility( HIDDEN );
01645             break;
01646         case CSS_VAL_VISIBLE:
01647             style->setVisibility( VISIBLE );
01648             break;
01649         case CSS_VAL_COLLAPSE:
01650             style->setVisibility( COLLAPSE );
01651         default:
01652             break;
01653         }
01654         break;
01655     }
01656     case CSS_PROP_WHITE_SPACE:
01657         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01658             if(!parentNode) return;
01659             style->setWhiteSpace(parentStyle->whiteSpace());
01660             return;
01661         }
01662 
01663         if(!primitiveValue->getIdent()) return;
01664 
01665         EWhiteSpace s;
01666         switch(primitiveValue->getIdent()) {
01667         case CSS_VAL_NOWRAP:   s = NOWRAP;      break;
01668         case CSS_VAL_PRE:      s = PRE;         break;
01669         case CSS_VAL_NORMAL:
01670         default:               s = NORMAL;      break;
01671         }
01672         style->setWhiteSpace(s);
01673 
01674         break;
01675 
01676 // special properties (css_extensions)
01677 //    case CSS_PROP_AZIMUTH:
01678         // CSS2Azimuth
01679     case CSS_PROP_BACKGROUND_POSITION:
01680         // CSS2BackgroundPosition
01681         break;
01682     case CSS_PROP_BACKGROUND_POSITION_X:
01683       {
01684       if(!primitiveValue) break;
01685       Length l;
01686       int type = primitiveValue->primitiveType();
01687       if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
01688     l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
01689       else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
01690     l = Length((int)primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
01691       else
01692     return;
01693       style->setBackgroundXPosition(l);
01694       break;
01695       }
01696     case CSS_PROP_BACKGROUND_POSITION_Y:
01697       {
01698       if(!primitiveValue) break;
01699       Length l;
01700       int type = primitiveValue->primitiveType();
01701       if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
01702     l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
01703       else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
01704     l = Length((int)primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
01705       else
01706     return;
01707       style->setBackgroundYPosition(l);
01708       break;
01709       }
01710     case CSS_PROP_BORDER_SPACING:
01711         {
01712         if(!primitiveValue) break;
01713         short spacing = 0;
01714         spacing =  primitiveValue->computeLength(style, paintDeviceMetrics);
01715         style->setBorderSpacing(spacing);
01716         break;
01717         }
01718         // CSS2BorderSpacing
01719     case CSS_PROP_CURSOR:
01720         // CSS2Cursor
01721         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01722             if(!parentNode) return;
01723             style->setCursor(parentStyle->cursor());
01724             return;
01725         } else if(primitiveValue) {
01726         style->setCursor( (ECursor) (primitiveValue->getIdent() - CSS_VAL_AUTO) );
01727         }
01728         break;
01729 //    case CSS_PROP_PLAY_DURING:
01730         // CSS2PlayDuring
01731 // colors || inherit
01732     case CSS_PROP_BACKGROUND_COLOR:
01733     case CSS_PROP_BORDER_TOP_COLOR:
01734     case CSS_PROP_BORDER_RIGHT_COLOR:
01735     case CSS_PROP_BORDER_BOTTOM_COLOR:
01736     case CSS_PROP_BORDER_LEFT_COLOR:
01737     case CSS_PROP_COLOR:
01738     case CSS_PROP_OUTLINE_COLOR:
01739         // this property is an extension used to get HTML4 <font> right.
01740     case CSS_PROP_TEXT_DECORATION_COLOR:
01741         // ie scrollbar styling
01742     case CSS_PROP_SCROLLBAR_FACE_COLOR:
01743     case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
01744     case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
01745     case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
01746     case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
01747     case CSS_PROP_SCROLLBAR_TRACK_COLOR:
01748     case CSS_PROP_SCROLLBAR_ARROW_COLOR:
01749 
01750     {
01751         QColor col;
01752         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01753         {
01754             switch(prop->m_id)
01755             {
01756             case CSS_PROP_BACKGROUND_COLOR:
01757                 col = parentStyle->backgroundColor(); break;
01758             case CSS_PROP_BORDER_TOP_COLOR:
01759                 col = parentStyle->borderTopColor(); break;
01760             case CSS_PROP_BORDER_RIGHT_COLOR:
01761                 col = parentStyle->borderRightColor(); break;
01762             case CSS_PROP_BORDER_BOTTOM_COLOR:
01763                 col = parentStyle->borderBottomColor(); break;
01764             case CSS_PROP_BORDER_LEFT_COLOR:
01765                 col = parentStyle->borderLeftColor(); break;
01766             case CSS_PROP_COLOR:
01767                 col = parentStyle->color(); break;
01768             case CSS_PROP_OUTLINE_COLOR:
01769         col = parentStyle->outlineColor(); break;
01770             default:
01771             return;
01772         }
01773         } else {
01774             if(!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_RGBCOLOR) return;
01775             if(qAlpha(primitiveValue->getRGBColorValue()))
01776                 col.setRgb(primitiveValue->getRGBColorValue());
01777             if (primitiveValue->getRGBColorValue() == khtml::defaultTextColor)
01778                 col = element->getDocument()->textColor();
01779     }
01780         //kdDebug( 6080 ) << "applying color " << col.isValid() << endl;
01781         switch(prop->m_id)
01782         {
01783         case CSS_PROP_BACKGROUND_COLOR:
01784             style->setBackgroundColor(col); break;
01785         case CSS_PROP_BORDER_TOP_COLOR:
01786             style->setBorderTopColor(col); break;
01787         case CSS_PROP_BORDER_RIGHT_COLOR:
01788             style->setBorderRightColor(col); break;
01789         case CSS_PROP_BORDER_BOTTOM_COLOR:
01790             style->setBorderBottomColor(col); break;
01791         case CSS_PROP_BORDER_LEFT_COLOR:
01792             style->setBorderLeftColor(col); break;
01793         case CSS_PROP_COLOR:
01794             style->setColor(col); break;
01795         case CSS_PROP_TEXT_DECORATION_COLOR:
01796             style->setTextDecorationColor(col); break;
01797         case CSS_PROP_OUTLINE_COLOR:
01798             style->setOutlineColor(col); break;
01799         case CSS_PROP_SCROLLBAR_FACE_COLOR:
01800             style->setPaletteColor(QPalette::Active, QColorGroup::Button, col);
01801             style->setPaletteColor(QPalette::Inactive, QColorGroup::Button, col);
01802             break;
01803         case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
01804             style->setPaletteColor(QPalette::Active, QColorGroup::Shadow, col);
01805             style->setPaletteColor(QPalette::Inactive, QColorGroup::Shadow, col);
01806             break;
01807         case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
01808             style->setPaletteColor(QPalette::Active, QColorGroup::Light, col);
01809             style->setPaletteColor(QPalette::Inactive, QColorGroup::Light, col);
01810             break;
01811         case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
01812             break;
01813         case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
01814             style->setPaletteColor(QPalette::Active, QColorGroup::Dark, col);
01815             style->setPaletteColor(QPalette::Inactive, QColorGroup::Dark, col);
01816             break;
01817         case CSS_PROP_SCROLLBAR_TRACK_COLOR:
01818             style->setPaletteColor(QPalette::Active, QColorGroup::Mid, col);
01819             style->setPaletteColor(QPalette::Inactive, QColorGroup::Mid, col);
01820             style->setPaletteColor(QPalette::Active, QColorGroup::Background, col);
01821             style->setPaletteColor(QPalette::Inactive, QColorGroup::Background, col);
01822             // fall through
01823         case CSS_PROP_SCROLLBAR_BASE_COLOR:
01824             style->setPaletteColor(QPalette::Active, QColorGroup::Base, col);
01825             style->setPaletteColor(QPalette::Inactive, QColorGroup::Base, col);
01826             break;
01827         case CSS_PROP_SCROLLBAR_ARROW_COLOR:
01828             style->setPaletteColor(QPalette::Active, QColorGroup::ButtonText, col);
01829             style->setPaletteColor(QPalette::Inactive, QColorGroup::ButtonText, col);
01830             break;
01831         default:
01832             return;
01833         }
01834         return;
01835     }
01836     break;
01837 // uri || inherit
01838     case CSS_PROP_BACKGROUND_IMAGE:
01839     {
01840     khtml::CachedImage *image = 0;
01841         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01842         {
01843             if(!parentNode) return;
01844             image = parentStyle->backgroundImage();
01845         } else {
01846         if(!primitiveValue) return;
01847         image = static_cast<CSSImageValueImpl *>(primitiveValue)->image();
01848     }
01849         style->setBackgroundImage(image);
01850         //kdDebug( 6080 ) << "setting image in style to " << image->image() << endl;
01851         break;
01852     }
01853 //     case CSS_PROP_CUE_AFTER:
01854 //     case CSS_PROP_CUE_BEFORE:
01855 //         break;
01856     case CSS_PROP_LIST_STYLE_IMAGE:
01857     {
01858     khtml::CachedImage *image = 0;
01859         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01860         {
01861             if(!parentNode) return;
01862             image = parentStyle->listStyleImage();
01863         } else {
01864         if(!primitiveValue) return;
01865         image = static_cast<CSSImageValueImpl *>(primitiveValue)->image();
01866     }
01867         style->setListStyleImage(image);
01868         //kdDebug( 6080 ) << "setting image in list to " << image->image() << endl;
01869         break;
01870     }
01871 
01872 // length
01873     case CSS_PROP_BORDER_TOP_WIDTH:
01874     case CSS_PROP_BORDER_RIGHT_WIDTH:
01875     case CSS_PROP_BORDER_BOTTOM_WIDTH:
01876     case CSS_PROP_BORDER_LEFT_WIDTH:
01877     case CSS_PROP_OUTLINE_WIDTH:
01878     {
01879     short width = 3;
01880         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01881         {
01882             switch(prop->m_id)
01883             {
01884             case CSS_PROP_BORDER_TOP_WIDTH:
01885             width = parentStyle->borderTopWidth(); break;
01886             case CSS_PROP_BORDER_RIGHT_WIDTH:
01887             width = parentStyle->borderRightWidth(); break;
01888             case CSS_PROP_BORDER_BOTTOM_WIDTH:
01889             width = parentStyle->borderBottomWidth(); break;
01890             case CSS_PROP_BORDER_LEFT_WIDTH:
01891             width = parentStyle->borderLeftWidth(); break;
01892             case CSS_PROP_OUTLINE_WIDTH:
01893             width = parentStyle->outlineWidth(); break;
01894             default:
01895             return;
01896         }
01897             return;
01898         } else {
01899         if(!primitiveValue) break;
01900         switch(primitiveValue->getIdent())
01901         {
01902         case CSS_VAL_THIN:
01903             width = 1;
01904             break;
01905         case CSS_VAL_MEDIUM:
01906             width = 3;
01907             break;
01908         case CSS_VAL_THICK:
01909             width = 5;
01910             break;
01911         case CSS_VAL_INVALID:
01912             width = primitiveValue->computeLength(style, paintDeviceMetrics);
01913             break;
01914         default:
01915             return;
01916         }
01917     }
01918         if(width < 0) return;
01919         switch(prop->m_id)
01920         {
01921         case CSS_PROP_BORDER_TOP_WIDTH:
01922             style->setBorderTopWidth(width);
01923             break;
01924         case CSS_PROP_BORDER_RIGHT_WIDTH:
01925             style->setBorderRightWidth(width);
01926             break;
01927         case CSS_PROP_BORDER_BOTTOM_WIDTH:
01928             style->setBorderBottomWidth(width);
01929             break;
01930         case CSS_PROP_BORDER_LEFT_WIDTH:
01931             style->setBorderLeftWidth(width);
01932             break;
01933         case CSS_PROP_OUTLINE_WIDTH:
01934             style->setOutlineWidth(width);
01935             break;
01936         default:
01937             return;
01938         }
01939         return;
01940     }
01941 
01942     case CSS_PROP_MARKER_OFFSET:
01943     case CSS_PROP_LETTER_SPACING:
01944     case CSS_PROP_WORD_SPACING:
01945     {
01946     int width = 0;
01947         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01948         {
01949             if(!parentNode) return;
01950             switch(prop->m_id)
01951             {
01952             case CSS_PROP_MARKER_OFFSET:
01953                 // ###
01954                 return;
01955             case CSS_PROP_LETTER_SPACING:
01956                 width = parentStyle->letterSpacing(); break;
01957             case CSS_PROP_WORD_SPACING:
01958                 width = parentStyle->wordSpacing(); break;
01959             default:
01960                 return;
01961             }
01962         } else {
01963         if(!primitiveValue) return;
01964         width = primitiveValue->computeLength(style, paintDeviceMetrics);
01965     }
01966         switch(prop->m_id)
01967         {
01968         case CSS_PROP_LETTER_SPACING:
01969             style->setLetterSpacing(width);
01970             break;
01971         case CSS_PROP_WORD_SPACING:
01972             style->setWordSpacing(width);
01973             break;
01974             // ### needs the definitions in renderstyle
01975         case CSS_PROP_MARKER_OFFSET:
01976         default: break;
01977         }
01978         return;
01979     }
01980 
01981 // length, percent
01982     case CSS_PROP_MAX_WIDTH:
01983         // +none +inherit
01984         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
01985             apply = true;
01986     case CSS_PROP_TOP:
01987     case CSS_PROP_LEFT:
01988     case CSS_PROP_RIGHT:
01989         // http://www.w3.org/Style/css2-updates/REC-CSS2-19980512-errata
01990         // introduces static-position value for top, left & right
01991         if(prop->m_id != CSS_PROP_MAX_WIDTH && primitiveValue &&
01992            primitiveValue->getIdent() == CSS_VAL_STATIC_POSITION)
01993         {
01994             //kdDebug( 6080 ) << "found value=static-position" << endl;
01995             l = Length ( 0, Static );
01996             apply = true;
01997         }
01998     case CSS_PROP_BOTTOM:
01999     case CSS_PROP_WIDTH:
02000     case CSS_PROP_MIN_WIDTH:
02001     case CSS_PROP_MARGIN_TOP:
02002     case CSS_PROP_MARGIN_RIGHT:
02003     case CSS_PROP_MARGIN_BOTTOM:
02004     case CSS_PROP_MARGIN_LEFT:
02005         // +inherit +auto
02006         if(prop->m_id != CSS_PROP_MAX_WIDTH && primitiveValue &&
02007            primitiveValue->getIdent() == CSS_VAL_AUTO)
02008         {
02009             //kdDebug( 6080 ) << "found value=auto" << endl;
02010             apply = true;
02011         }
02012     case CSS_PROP_PADDING_TOP:
02013     case CSS_PROP_PADDING_RIGHT:
02014     case CSS_PROP_PADDING_BOTTOM:
02015     case CSS_PROP_PADDING_LEFT:
02016     case CSS_PROP_TEXT_INDENT:
02017         // +inherit
02018     {
02019         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
02020             if(!parentNode) return;
02021         apply = true;
02022             switch(prop->m_id)
02023                 {
02024                 case CSS_PROP_MAX_WIDTH:
02025                     l = parentStyle->maxWidth(); break;
02026                 case CSS_PROP_BOTTOM:
02027                     l = parentStyle->bottom(); break;
02028                 case CSS_PROP_TOP:
02029                     l = parentStyle->top(); break;
02030                 case CSS_PROP_LEFT:
02031                     l = parentStyle->left(); break;
02032                 case CSS_PROP_RIGHT:
02033                     l = parentStyle->right(); break;
02034                 case CSS_PROP_WIDTH:
02035                     l = parentStyle->width(); break;
02036                 case CSS_PROP_MIN_WIDTH:
02037                     l = parentStyle->minWidth(); break;
02038                 case CSS_PROP_PADDING_TOP:
02039                     l = parentStyle->paddingTop(); break;
02040                 case CSS_PROP_PADDING_RIGHT:
02041                     l = parentStyle->paddingRight(); break;
02042                 case CSS_PROP_PADDING_BOTTOM:
02043                     l = parentStyle->paddingBottom(); break;
02044                 case CSS_PROP_PADDING_LEFT:
02045                     l = parentStyle->paddingLeft(); break;
02046                 case CSS_PROP_MARGIN_TOP:
02047                     l = parentStyle->marginTop(); break;
02048                 case CSS_PROP_MARGIN_RIGHT:
02049                     l = parentStyle->marginRight(); break;
02050                 case CSS_PROP_MARGIN_BOTTOM:
02051                     l = parentStyle->marginBottom(); break;
02052                 case CSS_PROP_MARGIN_LEFT:
02053                     l = parentStyle->marginLeft(); break;
02054                 case CSS_PROP_TEXT_INDENT:
02055                     l = parentStyle->textIndent(); break;
02056                 default:
02057                     return;
02058                 }
02059         } else if(primitiveValue && !apply) {
02060             int type = primitiveValue->primitiveType();
02061             if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02062                 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02063             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02064                 l = Length((int)primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02065         else if (type == CSSPrimitiveValue::CSS_HTML_RELATIVE)
02066         l = Length(int(primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_HTML_RELATIVE)), Relative);
02067             else
02068                 return;
02069             apply = true;
02070         }
02071         if(!apply) return;
02072         switch(prop->m_id)
02073             {
02074             case CSS_PROP_MAX_WIDTH:
02075                 style->setMaxWidth(l); break;
02076             case CSS_PROP_BOTTOM:
02077                 style->setBottom(l); break;
02078             case CSS_PROP_TOP:
02079                 style->setTop(l); break;
02080             case CSS_PROP_LEFT:
02081                 style->setLeft(l); break;
02082             case CSS_PROP_RIGHT:
02083                 style->setRight(l); break;
02084             case CSS_PROP_WIDTH:
02085                 style->setWidth(l); break;
02086             case CSS_PROP_MIN_WIDTH:
02087                 style->setMinWidth(l); break;
02088             case CSS_PROP_PADDING_TOP:
02089                 style->setPaddingTop(l); break;
02090             case CSS_PROP_PADDING_RIGHT:
02091                 style->setPaddingRight(l); break;
02092             case CSS_PROP_PADDING_BOTTOM:
02093                 style->setPaddingBottom(l); break;
02094             case CSS_PROP_PADDING_LEFT:
02095                 style->setPaddingLeft(l); break;
02096             case CSS_PROP_MARGIN_TOP:
02097                 style->setMarginTop(l); break;
02098             case CSS_PROP_MARGIN_RIGHT:
02099                 style->setMarginRight(l); break;
02100             case CSS_PROP_MARGIN_BOTTOM:
02101                 style->setMarginBottom(l); break;
02102             case CSS_PROP_MARGIN_LEFT:
02103                 style->setMarginLeft(l); break;
02104             case CSS_PROP_TEXT_INDENT:
02105                 style->setTextIndent(l); break;
02106             default: break;
02107             }
02108         return;
02109     }
02110 
02111     case CSS_PROP_MAX_HEIGHT:
02112         // +inherit +none !can be calculted directly!
02113         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
02114             apply = true;
02115     case CSS_PROP_HEIGHT:
02116     case CSS_PROP_MIN_HEIGHT:
02117         // +inherit +auto !can be calculted directly!
02118         if(!prop->m_id == CSS_PROP_MAX_HEIGHT && primitiveValue &&
02119            primitiveValue->getIdent() == CSS_VAL_AUTO)
02120             apply = true;
02121         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02122         {
02123             if(!parentNode) return;
02124         apply = true;
02125             switch(prop->m_id)
02126                 {
02127                 case CSS_PROP_MAX_HEIGHT:
02128                     l = parentStyle->maxHeight(); break;
02129                 case CSS_PROP_HEIGHT:
02130                     l = parentStyle->height(); break;
02131                 case CSS_PROP_MIN_HEIGHT:
02132                     l = parentStyle->minHeight(); break;
02133                 default:
02134                     return;
02135                 }
02136         }
02137         if(primitiveValue && !apply)
02138         {
02139             int type = primitiveValue->primitiveType();
02140             if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02141                 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02142             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02143             {
02144                 // ### compute from parents height!!!
02145                 l = Length((int)primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02146             }
02147             else
02148                 return;
02149             apply = true;
02150         }
02151         if(!apply) return;
02152         switch(prop->m_id)
02153         {
02154         case CSS_PROP_MAX_HEIGHT:
02155             style->setMaxHeight(l); break;
02156         case CSS_PROP_HEIGHT:
02157             style->setHeight(l); break;
02158         case CSS_PROP_MIN_HEIGHT:
02159             style->setMinHeight(l); break;
02160         default:
02161             return;
02162         }
02163         return;
02164 
02165         break;
02166 
02167     case CSS_PROP_VERTICAL_ALIGN:
02168         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02169         {
02170             if(!parentNode) return;
02171             style->setVerticalAlign(parentStyle->verticalAlign());
02172             return;
02173         }
02174         if(!primitiveValue) return;
02175         if(primitiveValue->getIdent()) {
02176 
02177       khtml::EVerticalAlign align;
02178 
02179       switch(primitiveValue->getIdent())
02180         {
02181         case CSS_VAL_TOP:
02182             align = TOP; break;
02183         case CSS_VAL_BOTTOM:
02184             align = BOTTOM; break;
02185         case CSS_VAL_MIDDLE:
02186             align = MIDDLE; break;
02187         case CSS_VAL_BASELINE:
02188             align = BASELINE; break;
02189         case CSS_VAL_TEXT_BOTTOM:
02190             align = TEXT_BOTTOM; break;
02191         case CSS_VAL_TEXT_TOP:
02192             align = TEXT_TOP; break;
02193         case CSS_VAL_SUB:
02194             align = SUB; break;
02195         case CSS_VAL_SUPER:
02196             align = SUPER; break;
02197         case CSS_VAL__KONQ_BASELINE_MIDDLE:
02198             align = BASELINE_MIDDLE; break;
02199         default:
02200             return;
02201         }
02202       style->setVerticalAlign(align);
02203       return;
02204         } else {
02205       int type = primitiveValue->primitiveType();
02206       Length l;
02207       if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02208         l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed );
02209       else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02210         l = Length( int( primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE) ), Percent );
02211 
02212       style->setVerticalAlign( LENGTH );
02213       style->setVerticalAlignLength( l );
02214     }
02215         break;
02216 
02217     case CSS_PROP_FONT_SIZE:
02218     {
02219         FontDef fontDef = style->htmlFont().fontDef;
02220         int oldSize;
02221         float size = 0;
02222 
02223         float toPix = paintDeviceMetrics->logicalDpiY()/72.;
02224         if (toPix  < 96./72.) toPix = 96./72.;
02225 
02226         int minFontSize = int(settings->minFontSize() * toPix);
02227 
02228         if(parentNode) {
02229             oldSize = parentStyle->font().pixelSize();
02230         } else
02231             oldSize = m_fontSizes[3];
02232 
02233         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
02234             size = oldSize;
02235         } else if(primitiveValue->getIdent()) {
02236             switch(primitiveValue->getIdent())
02237             {
02238             case CSS_VAL_XX_SMALL: size = m_fontSizes[0]; break;
02239             case CSS_VAL_X_SMALL:  size = m_fontSizes[1]; break;
02240             case CSS_VAL_SMALL:    size = m_fontSizes[2]; break;
02241             case CSS_VAL_MEDIUM:   size = m_fontSizes[3]; break;
02242             case CSS_VAL_LARGE:    size = m_fontSizes[4]; break;
02243             case CSS_VAL_X_LARGE:  size = m_fontSizes[5]; break;
02244             case CSS_VAL_XX_LARGE: size = m_fontSizes[6]; break;
02245             case CSS_VAL__KONQ_XXX_LARGE:  size = ( m_fontSizes[6]*5 )/3; break;
02246             case CSS_VAL_LARGER:
02247                 // ### use the next bigger standardSize!!!
02248                 size = oldSize * 1.2;
02249                 break;
02250             case CSS_VAL_SMALLER:
02251                 size = oldSize / 1.2;
02252                 break;
02253             default:
02254                 return;
02255             }
02256 
02257         } else {
02258             int type = primitiveValue->primitiveType();
02259             if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02260                 size = primitiveValue->computeLengthFloat(parentStyle, paintDeviceMetrics);
02261             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02262                 size = (primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE)
02263                         * parentStyle->font().pixelSize()) / 100;
02264             else
02265                 return;
02266 
02267             if (!khtml::printpainter && element && element->getDocument()->view())
02268                 size *= element->getDocument()->view()->part()->zoomFactor() / 100.0;
02269         }
02270 
02271         if(size <= 0) return;
02272 
02273         // we never want to get smaller than the minimum font size to keep fonts readable
02274         if(size < minFontSize ) size = minFontSize;
02275 
02276         //kdDebug( 6080 ) << "computed raw font size: " << size << endl;
02277 
02278     fontDef.size = int(size);
02279         if (style->setFontDef( fontDef ))
02280     fontDirty = true;
02281         return;
02282     }
02283 
02284 // angle
02285 //    case CSS_PROP_ELEVATION:
02286 
02287 // number
02288 //     case CSS_PROP_FONT_SIZE_ADJUST:
02289 //     case CSS_PROP_ORPHANS:
02290 //     case CSS_PROP_PITCH_RANGE:
02291 //     case CSS_PROP_RICHNESS:
02292 //     case CSS_PROP_SPEECH_RATE:
02293 //     case CSS_PROP_STRESS:
02294 //     case CSS_PROP_WIDOWS:
02295         break;
02296     case CSS_PROP_Z_INDEX:
02297     {
02298     int z_index = 0;
02299         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02300        {
02301             if(!parentNode) return;
02302             z_index = parentStyle->zIndex();
02303         } else {
02304             if(!primitiveValue ||
02305                primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
02306                 return;
02307         z_index = (int)primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_NUMBER);
02308     }
02309         style->setZIndex( z_index );
02310         return;
02311     }
02312 
02313 // length, percent, number
02314     case CSS_PROP_LINE_HEIGHT:
02315     {
02316         Length lineHeight;
02317         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02318         {
02319             if(!parentNode) return;
02320             lineHeight = parentStyle->lineHeight();
02321         } else {
02322             if(!primitiveValue) return;
02323             int type = primitiveValue->primitiveType();
02324             if(primitiveValue->getIdent() == CSS_VAL_NORMAL)
02325                 lineHeight = Length( -100, Percent );
02326             else if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02327                 lineHeight = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02328             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02329                 lineHeight = Length( ( style->font().pixelSize() * int(primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE)) ) / 100, Fixed );
02330             else if(type == CSSPrimitiveValue::CSS_NUMBER)
02331                 lineHeight = Length(int(primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_NUMBER)*100), Percent);
02332             else
02333                 return;
02334     }
02335         style->setLineHeight(lineHeight);
02336         return;
02337     }
02338 
02339 // number, percent
02340 //    case CSS_PROP_VOLUME:
02341 
02342 // frequency
02343 //    case CSS_PROP_PITCH:
02344 //        break;
02345 
02346 // string
02347     case CSS_PROP_TEXT_ALIGN:
02348     {
02349         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02350         {
02351             if(!parentNode) return;
02352             style->setTextAlign(parentStyle->textAlign());
02353             return;
02354         }
02355         if(!primitiveValue) return;
02356         if(primitiveValue->getIdent())
02357             style->setTextAlign( (ETextAlign) (primitiveValue->getIdent() - CSS_VAL__KONQ_AUTO) );
02358     return;
02359     }
02360 
02361 // rect
02362     case CSS_PROP_CLIP:
02363     {
02364     Length top;
02365     Length right;
02366     Length bottom;
02367     Length left;
02368     if ( value->cssValueType() == CSSValue::CSS_INHERIT ) {
02369         top = parentStyle->clipTop();
02370         right = parentStyle->clipRight();
02371         bottom = parentStyle->clipBottom();
02372         left = parentStyle->clipLeft();
02373     } else if ( !primitiveValue ) {
02374         break;
02375     } else if ( primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RECT ) {
02376         RectImpl *rect = primitiveValue->getRectValue();
02377         if ( !rect )
02378         break;
02379         top = convertToLength( rect->top(), style, paintDeviceMetrics );
02380         right = convertToLength( rect->right(), style, paintDeviceMetrics );
02381         bottom = convertToLength( rect->bottom(), style, paintDeviceMetrics );
02382         left = convertToLength( rect->left(), style, paintDeviceMetrics );
02383 
02384     } else if ( primitiveValue->getIdent() != CSS_VAL_AUTO ) {
02385         break;
02386     }
02387 //  qDebug("setting clip top to %d", top.value );
02388 //  qDebug("setting clip right to %d", right.value );
02389 //  qDebug("setting clip bottom to %d", bottom.value );
02390 //  qDebug("setting clip left to %d", left.value );
02391     style->setClip( top, right, bottom, left );
02392     style->setClipSpecified( true );
02393         // rect, ident
02394         break;
02395     }
02396 
02397 // lists
02398     case CSS_PROP_CONTENT:
02399         // list of string, uri, counter, attr, i
02400     {
02401         if (!(style->styleType()==RenderStyle::BEFORE ||
02402                 style->styleType()==RenderStyle::AFTER))
02403             break;
02404 
02405         if(!value->isValueList()) return;
02406         CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
02407         int len = list->length();
02408 
02409         for(int i = 0; i < len; i++) {
02410             CSSValueImpl *item = list->item(i);
02411             if(!item->isPrimitiveValue()) continue;
02412             CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item);
02413             if(val->primitiveType()==CSSPrimitiveValue::CSS_STRING)
02414             {
02415                 style->setContent(val->getStringValue());
02416             }
02417             else if (val->primitiveType()==CSSPrimitiveValue::CSS_URI)
02418             {
02419                 CSSImageValueImpl *image = static_cast<CSSImageValueImpl *>(val);
02420                 style->setContent(image->image());
02421             }
02422 
02423         }
02424         break;
02425     }
02426 
02427     case CSS_PROP_COUNTER_INCREMENT:
02428         // list of CSS2CounterIncrement
02429     case CSS_PROP_COUNTER_RESET:
02430         // list of CSS2CounterReset
02431         break;
02432     case CSS_PROP_FONT_FAMILY:
02433         // list of strings and ids
02434     {
02435         if(!value->isValueList()) return;
02436     FontDef fontDef = style->htmlFont().fontDef;
02437         CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
02438         int len = list->length();
02439     QString family;
02440         for(int i = 0; i < len; i++) {
02441             CSSValueImpl *item = list->item(i);
02442             if(!item->isPrimitiveValue()) continue;
02443             CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item);
02444             if(!val->primitiveType() == CSSPrimitiveValue::CSS_STRING) return;
02445             QString face = static_cast<FontFamilyValueImpl *>(val)->fontName();
02446         if ( !face.isNull() || face.isEmpty() ) {
02447         if(face == "serif") {
02448             face = settings->serifFontName();
02449         }
02450         else if(face == "sans-serif") {
02451             face = settings->sansSerifFontName();
02452         }
02453         else if( face == "cursive") {
02454             face = settings->cursiveFontName();
02455         }
02456         else if( face == "fantasy") {
02457             face = settings->fantasyFontName();
02458         }
02459         else if( face == "monospace") {
02460             face = settings->fixedFontName();
02461         }
02462         else if( face == "konq_default") {
02463             face = settings->stdFontName();
02464         }
02465         if ( !face.isEmpty() ) {
02466             fontDef.family = face;
02467             if (style->setFontDef( fontDef ))
02468             fontDirty = true;
02469         }
02470                 return;
02471         }
02472         }
02473         break;
02474     }
02475     case CSS_PROP_QUOTES:
02476         // list of strings or i
02477     case CSS_PROP_SIZE:
02478         // ### look up
02479       break;
02480     case CSS_PROP_TEXT_DECORATION:
02481         // list of ident
02482         // ### no list at the moment
02483     {
02484         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02485         {
02486             if(!parentNode) return;
02487             style->setTextDecoration(parentStyle->textDecoration());
02488             style->setTextDecorationColor(parentStyle->textDecorationColor());
02489             return;
02490         }
02491         int t = TDNONE;
02492         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) {
02493         // do nothing
02494     } else {
02495         if(!value->isValueList()) return;
02496         CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
02497         int len = list->length();
02498         for(int i = 0; i < len; i++)
02499         {
02500         CSSValueImpl *item = list->item(i);
02501         if(!item->isPrimitiveValue()) continue;
02502         primitiveValue = static_cast<CSSPrimitiveValueImpl *>(item);
02503         switch(primitiveValue->getIdent())
02504         {
02505             case CSS_VAL_NONE:
02506             t = TDNONE; break;
02507             case CSS_VAL_UNDERLINE:
02508             t |= UNDERLINE; break;
02509             case CSS_VAL_OVERLINE:
02510             t |= OVERLINE; break;
02511             case CSS_VAL_LINE_THROUGH:
02512             t |= LINE_THROUGH; break;
02513             case CSS_VAL_BLINK:
02514             t |= BLINK; break;
02515             default:
02516             return;
02517         }
02518         }
02519         }
02520     style->setTextDecoration(t);
02521     style->setTextDecorationColor(style->color());
02522         break;
02523     }
02524     case CSS_PROP__KONQ_FLOW_MODE:
02525         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02526         {
02527             if(!parentNode) return;
02528             style->setFlowAroundFloats(parentStyle->flowAroundFloats());
02529             return;
02530         }
02531         if(!primitiveValue) return;
02532         if(primitiveValue->getIdent())
02533         {
02534             style->setFlowAroundFloats( primitiveValue->getIdent() == CSS_VAL__KONQ_AROUND_FLOATS );
02535             return;
02536         }
02537         break;
02538 //     case CSS_PROP_VOICE_FAMILY:
02539 //         // list of strings and i
02540 //         break;
02541 
02542 // shorthand properties
02543     case CSS_PROP_BACKGROUND:
02544         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02545         style->setBackgroundColor(parentStyle->backgroundColor());
02546         style->setBackgroundImage(parentStyle->backgroundImage());
02547         style->setBackgroundRepeat(parentStyle->backgroundRepeat());
02548         style->setBackgroundAttachment(parentStyle->backgroundAttachment());
02549 //      style->setBackgroundPosition(parentStyle->backgroundPosition());
02550 
02551         break;
02552     case CSS_PROP_BORDER_COLOR:
02553         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_TRANSPARENT)
02554         {
02555             style->setBorderTopColor(QColor());
02556             style->setBorderBottomColor(QColor());
02557             style->setBorderLeftColor(QColor());
02558             style->setBorderRightColor(QColor());
02559             return;
02560         }
02561     case CSS_PROP_BORDER:
02562     case CSS_PROP_BORDER_STYLE:
02563     case CSS_PROP_BORDER_WIDTH:
02564         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02565 
02566         if(prop->m_id == CSS_PROP_BORDER || prop->m_id == CSS_PROP_BORDER_COLOR)
02567         {
02568             style->setBorderTopColor(parentStyle->borderTopColor());
02569             style->setBorderBottomColor(parentStyle->borderBottomColor());
02570             style->setBorderLeftColor(parentStyle->borderLeftColor());
02571             style->setBorderRightColor(parentStyle->borderRightColor());
02572         }
02573         if(prop->m_id == CSS_PROP_BORDER || prop->m_id == CSS_PROP_BORDER_STYLE)
02574         {
02575             style->setBorderTopStyle(parentStyle->borderTopStyle());
02576             style->setBorderBottomStyle(parentStyle->borderBottomStyle());
02577             style->setBorderLeftStyle(parentStyle->borderLeftStyle());
02578             style->setBorderRightStyle(parentStyle->borderRightStyle());
02579         }
02580         if(prop->m_id == CSS_PROP_BORDER || prop->m_id == CSS_PROP_BORDER_WIDTH)
02581         {
02582             style->setBorderTopWidth(parentStyle->borderTopWidth());
02583             style->setBorderBottomWidth(parentStyle->borderBottomWidth());
02584             style->setBorderLeftWidth(parentStyle->borderLeftWidth());
02585             style->setBorderRightWidth(parentStyle->borderRightWidth());
02586         }
02587         return;
02588     case CSS_PROP_BORDER_TOP:
02589         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02590         style->setBorderTopColor(parentStyle->borderTopColor());
02591         style->setBorderTopStyle(parentStyle->borderTopStyle());
02592         style->setBorderTopWidth(parentStyle->borderTopWidth());
02593         return;
02594     case CSS_PROP_BORDER_RIGHT:
02595         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02596         style->setBorderRightColor(parentStyle->borderRightColor());
02597         style->setBorderRightStyle(parentStyle->borderRightStyle());
02598         style->setBorderRightWidth(parentStyle->borderRightWidth());
02599         return;
02600     case CSS_PROP_BORDER_BOTTOM:
02601         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02602         style->setBorderBottomColor(parentStyle->borderBottomColor());
02603         style->setBorderBottomStyle(parentStyle->borderBottomStyle());
02604         style->setBorderBottomWidth(parentStyle->borderBottomWidth());
02605         return;
02606     case CSS_PROP_BORDER_LEFT:
02607         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02608         style->setBorderLeftColor(parentStyle->borderLeftColor());
02609         style->setBorderLeftStyle(parentStyle->borderLeftStyle());
02610         style->setBorderLeftWidth(parentStyle->borderLeftWidth());
02611         return;
02612     case CSS_PROP_MARGIN:
02613         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02614         style->setMarginTop(parentStyle->marginTop());
02615         style->setMarginBottom(parentStyle->marginBottom());
02616         style->setMarginLeft(parentStyle->marginLeft());
02617         style->setMarginRight(parentStyle->marginRight());
02618         return;
02619     case CSS_PROP_PADDING:
02620         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02621         style->setPaddingTop(parentStyle->paddingTop());
02622         style->setPaddingBottom(parentStyle->paddingBottom());
02623         style->setPaddingLeft(parentStyle->paddingLeft());
02624         style->setPaddingRight(parentStyle->paddingRight());
02625         return;
02626 
02627 //     case CSS_PROP_CUE:
02628     case CSS_PROP_FONT:
02629     case CSS_PROP_LIST_STYLE:
02630     case CSS_PROP_OUTLINE:
02631 //    case CSS_PROP_PAUSE:
02632         break;
02633     default:
02634         return;
02635     }
02636 }
02637 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:22:35 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001