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(value->cssValueType() == CSSValue::CSS_INHERIT) {
01578             if(parentNode)
01579         style->setTableLayout(parentStyle->tableLayout());
01580             return;
01581         }
01582 
01583     if ( !primitiveValue )
01584         return;
01585 
01586     ETableLayout l = TAUTO;
01587     switch( primitiveValue->getIdent() ) {
01588     case CSS_VAL_FIXED:
01589         l = TFIXED;
01590         // fall through
01591     case CSS_VAL_AUTO:
01592         style->setTableLayout( l );
01593     default:
01594         break;
01595     }
01596     break;
01597     }
01598     case CSS_PROP_UNICODE_BIDI: {
01599     EUnicodeBidi b = UBNormal;
01600         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01601             if(!parentNode) return;
01602             b = parentStyle->unicodeBidi();
01603         } else {
01604         switch( primitiveValue->getIdent() ) {
01605         case CSS_VAL_NORMAL:
01606             b = UBNormal; break;
01607         case CSS_VAL_EMBED:
01608             b = Embed; break;
01609         case CSS_VAL_BIDI_OVERRIDE:
01610             b = Override; break;
01611         default:
01612             return;
01613         }
01614     }
01615     style->setUnicodeBidi( b );
01616         break;
01617     }
01618     case CSS_PROP_TEXT_TRANSFORM:
01619         {
01620         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01621             if(!parentNode) return;
01622             style->setTextTransform(parentStyle->textTransform());
01623             return;
01624         }
01625 
01626         if(!primitiveValue->getIdent()) return;
01627 
01628         ETextTransform tt;
01629         switch(primitiveValue->getIdent()) {
01630         case CSS_VAL_CAPITALIZE:  tt = CAPITALIZE;  break;
01631         case CSS_VAL_UPPERCASE:   tt = UPPERCASE;   break;
01632         case CSS_VAL_LOWERCASE:   tt = LOWERCASE;   break;
01633         case CSS_VAL_NONE:
01634         default:                  tt = TTNONE;      break;
01635         }
01636         style->setTextTransform(tt);
01637         break;
01638         }
01639 
01640     case CSS_PROP_VISIBILITY:
01641     {
01642         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01643             if(!parentNode) return;
01644             style->setVisibility(parentStyle->visibility());
01645             return;
01646         }
01647 
01648         switch( primitiveValue->getIdent() ) {
01649         case CSS_VAL_HIDDEN:
01650             style->setVisibility( HIDDEN );
01651             break;
01652         case CSS_VAL_VISIBLE:
01653             style->setVisibility( VISIBLE );
01654             break;
01655         case CSS_VAL_COLLAPSE:
01656             style->setVisibility( COLLAPSE );
01657         default:
01658             break;
01659         }
01660         break;
01661     }
01662     case CSS_PROP_WHITE_SPACE:
01663         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01664             if(!parentNode) return;
01665             style->setWhiteSpace(parentStyle->whiteSpace());
01666             return;
01667         }
01668 
01669         if(!primitiveValue->getIdent()) return;
01670 
01671         EWhiteSpace s;
01672         switch(primitiveValue->getIdent()) {
01673         case CSS_VAL_NOWRAP:   s = NOWRAP;      break;
01674         case CSS_VAL_PRE:      s = PRE;         break;
01675         case CSS_VAL_NORMAL:
01676         default:               s = NORMAL;      break;
01677         }
01678         style->setWhiteSpace(s);
01679 
01680         break;
01681 
01682 // special properties (css_extensions)
01683 //    case CSS_PROP_AZIMUTH:
01684         // CSS2Azimuth
01685     case CSS_PROP_BACKGROUND_POSITION:
01686         // CSS2BackgroundPosition
01687         break;
01688     case CSS_PROP_BACKGROUND_POSITION_X:
01689       {
01690       if(!primitiveValue) break;
01691       Length l;
01692       int type = primitiveValue->primitiveType();
01693       if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
01694     l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
01695       else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
01696     l = Length((int)primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
01697       else
01698     return;
01699       style->setBackgroundXPosition(l);
01700       break;
01701       }
01702     case CSS_PROP_BACKGROUND_POSITION_Y:
01703       {
01704       if(!primitiveValue) break;
01705       Length l;
01706       int type = primitiveValue->primitiveType();
01707       if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
01708     l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
01709       else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
01710     l = Length((int)primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
01711       else
01712     return;
01713       style->setBackgroundYPosition(l);
01714       break;
01715       }
01716     case CSS_PROP_BORDER_SPACING:
01717         {
01718         if(!primitiveValue) break;
01719         short spacing = 0;
01720         spacing =  primitiveValue->computeLength(style, paintDeviceMetrics);
01721         style->setBorderSpacing(spacing);
01722         break;
01723         }
01724         // CSS2BorderSpacing
01725     case CSS_PROP_CURSOR:
01726         // CSS2Cursor
01727         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
01728             if(!parentNode) return;
01729             style->setCursor(parentStyle->cursor());
01730             return;
01731         } else if(primitiveValue) {
01732         style->setCursor( (ECursor) (primitiveValue->getIdent() - CSS_VAL_AUTO) );
01733         }
01734         break;
01735 //    case CSS_PROP_PLAY_DURING:
01736         // CSS2PlayDuring
01737 // colors || inherit
01738     case CSS_PROP_BACKGROUND_COLOR:
01739     case CSS_PROP_BORDER_TOP_COLOR:
01740     case CSS_PROP_BORDER_RIGHT_COLOR:
01741     case CSS_PROP_BORDER_BOTTOM_COLOR:
01742     case CSS_PROP_BORDER_LEFT_COLOR:
01743     case CSS_PROP_COLOR:
01744     case CSS_PROP_OUTLINE_COLOR:
01745         // this property is an extension used to get HTML4 <font> right.
01746     case CSS_PROP_TEXT_DECORATION_COLOR:
01747         // ie scrollbar styling
01748     case CSS_PROP_SCROLLBAR_FACE_COLOR:
01749     case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
01750     case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
01751     case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
01752     case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
01753     case CSS_PROP_SCROLLBAR_TRACK_COLOR:
01754     case CSS_PROP_SCROLLBAR_ARROW_COLOR:
01755 
01756     {
01757         QColor col;
01758         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01759         {
01760             switch(prop->m_id)
01761             {
01762             case CSS_PROP_BACKGROUND_COLOR:
01763                 col = parentStyle->backgroundColor(); break;
01764             case CSS_PROP_BORDER_TOP_COLOR:
01765                 col = parentStyle->borderTopColor(); break;
01766             case CSS_PROP_BORDER_RIGHT_COLOR:
01767                 col = parentStyle->borderRightColor(); break;
01768             case CSS_PROP_BORDER_BOTTOM_COLOR:
01769                 col = parentStyle->borderBottomColor(); break;
01770             case CSS_PROP_BORDER_LEFT_COLOR:
01771                 col = parentStyle->borderLeftColor(); break;
01772             case CSS_PROP_COLOR:
01773                 col = parentStyle->color(); break;
01774             case CSS_PROP_OUTLINE_COLOR:
01775         col = parentStyle->outlineColor(); break;
01776             default:
01777             return;
01778         }
01779         } else {
01780             if(!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_RGBCOLOR) return;
01781             if(qAlpha(primitiveValue->getRGBColorValue()))
01782                 col.setRgb(primitiveValue->getRGBColorValue());
01783             if (primitiveValue->getRGBColorValue() == khtml::defaultTextColor)
01784                 col = element->getDocument()->textColor();
01785     }
01786         //kdDebug( 6080 ) << "applying color " << col.isValid() << endl;
01787         switch(prop->m_id)
01788         {
01789         case CSS_PROP_BACKGROUND_COLOR:
01790             style->setBackgroundColor(col); break;
01791         case CSS_PROP_BORDER_TOP_COLOR:
01792             style->setBorderTopColor(col); break;
01793         case CSS_PROP_BORDER_RIGHT_COLOR:
01794             style->setBorderRightColor(col); break;
01795         case CSS_PROP_BORDER_BOTTOM_COLOR:
01796             style->setBorderBottomColor(col); break;
01797         case CSS_PROP_BORDER_LEFT_COLOR:
01798             style->setBorderLeftColor(col); break;
01799         case CSS_PROP_COLOR:
01800             style->setColor(col); break;
01801         case CSS_PROP_TEXT_DECORATION_COLOR:
01802             style->setTextDecorationColor(col); break;
01803         case CSS_PROP_OUTLINE_COLOR:
01804             style->setOutlineColor(col); break;
01805         case CSS_PROP_SCROLLBAR_FACE_COLOR:
01806             style->setPaletteColor(QPalette::Active, QColorGroup::Button, col);
01807             style->setPaletteColor(QPalette::Inactive, QColorGroup::Button, col);
01808             break;
01809         case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
01810             style->setPaletteColor(QPalette::Active, QColorGroup::Shadow, col);
01811             style->setPaletteColor(QPalette::Inactive, QColorGroup::Shadow, col);
01812             break;
01813         case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
01814             style->setPaletteColor(QPalette::Active, QColorGroup::Light, col);
01815             style->setPaletteColor(QPalette::Inactive, QColorGroup::Light, col);
01816             break;
01817         case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
01818             break;
01819         case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
01820             style->setPaletteColor(QPalette::Active, QColorGroup::Dark, col);
01821             style->setPaletteColor(QPalette::Inactive, QColorGroup::Dark, col);
01822             break;
01823         case CSS_PROP_SCROLLBAR_TRACK_COLOR:
01824             style->setPaletteColor(QPalette::Active, QColorGroup::Mid, col);
01825             style->setPaletteColor(QPalette::Inactive, QColorGroup::Mid, col);
01826             style->setPaletteColor(QPalette::Active, QColorGroup::Background, col);
01827             style->setPaletteColor(QPalette::Inactive, QColorGroup::Background, col);
01828             // fall through
01829         case CSS_PROP_SCROLLBAR_BASE_COLOR:
01830             style->setPaletteColor(QPalette::Active, QColorGroup::Base, col);
01831             style->setPaletteColor(QPalette::Inactive, QColorGroup::Base, col);
01832             break;
01833         case CSS_PROP_SCROLLBAR_ARROW_COLOR:
01834             style->setPaletteColor(QPalette::Active, QColorGroup::ButtonText, col);
01835             style->setPaletteColor(QPalette::Inactive, QColorGroup::ButtonText, col);
01836             break;
01837         default:
01838             return;
01839         }
01840         return;
01841     }
01842     break;
01843 // uri || inherit
01844     case CSS_PROP_BACKGROUND_IMAGE:
01845     {
01846     khtml::CachedImage *image = 0;
01847         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01848         {
01849             if(!parentNode) return;
01850             image = parentStyle->backgroundImage();
01851         } else {
01852         if(!primitiveValue) return;
01853         image = static_cast<CSSImageValueImpl *>(primitiveValue)->image();
01854     }
01855         style->setBackgroundImage(image);
01856         //kdDebug( 6080 ) << "setting image in style to " << image->image() << endl;
01857         break;
01858     }
01859 //     case CSS_PROP_CUE_AFTER:
01860 //     case CSS_PROP_CUE_BEFORE:
01861 //         break;
01862     case CSS_PROP_LIST_STYLE_IMAGE:
01863     {
01864     khtml::CachedImage *image = 0;
01865         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01866         {
01867             if(!parentNode) return;
01868             image = parentStyle->listStyleImage();
01869         } else {
01870         if(!primitiveValue) return;
01871         image = static_cast<CSSImageValueImpl *>(primitiveValue)->image();
01872     }
01873         style->setListStyleImage(image);
01874         //kdDebug( 6080 ) << "setting image in list to " << image->image() << endl;
01875         break;
01876     }
01877 
01878 // length
01879     case CSS_PROP_BORDER_TOP_WIDTH:
01880     case CSS_PROP_BORDER_RIGHT_WIDTH:
01881     case CSS_PROP_BORDER_BOTTOM_WIDTH:
01882     case CSS_PROP_BORDER_LEFT_WIDTH:
01883     case CSS_PROP_OUTLINE_WIDTH:
01884     {
01885     short width = 3;
01886         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01887         {
01888             switch(prop->m_id)
01889             {
01890             case CSS_PROP_BORDER_TOP_WIDTH:
01891             width = parentStyle->borderTopWidth(); break;
01892             case CSS_PROP_BORDER_RIGHT_WIDTH:
01893             width = parentStyle->borderRightWidth(); break;
01894             case CSS_PROP_BORDER_BOTTOM_WIDTH:
01895             width = parentStyle->borderBottomWidth(); break;
01896             case CSS_PROP_BORDER_LEFT_WIDTH:
01897             width = parentStyle->borderLeftWidth(); break;
01898             case CSS_PROP_OUTLINE_WIDTH:
01899             width = parentStyle->outlineWidth(); break;
01900             default:
01901             return;
01902         }
01903             return;
01904         } else {
01905         if(!primitiveValue) break;
01906         switch(primitiveValue->getIdent())
01907         {
01908         case CSS_VAL_THIN:
01909             width = 1;
01910             break;
01911         case CSS_VAL_MEDIUM:
01912             width = 3;
01913             break;
01914         case CSS_VAL_THICK:
01915             width = 5;
01916             break;
01917         case CSS_VAL_INVALID:
01918             width = primitiveValue->computeLength(style, paintDeviceMetrics);
01919             break;
01920         default:
01921             return;
01922         }
01923     }
01924         if(width < 0) return;
01925         switch(prop->m_id)
01926         {
01927         case CSS_PROP_BORDER_TOP_WIDTH:
01928             style->setBorderTopWidth(width);
01929             break;
01930         case CSS_PROP_BORDER_RIGHT_WIDTH:
01931             style->setBorderRightWidth(width);
01932             break;
01933         case CSS_PROP_BORDER_BOTTOM_WIDTH:
01934             style->setBorderBottomWidth(width);
01935             break;
01936         case CSS_PROP_BORDER_LEFT_WIDTH:
01937             style->setBorderLeftWidth(width);
01938             break;
01939         case CSS_PROP_OUTLINE_WIDTH:
01940             style->setOutlineWidth(width);
01941             break;
01942         default:
01943             return;
01944         }
01945         return;
01946     }
01947 
01948     case CSS_PROP_MARKER_OFFSET:
01949     case CSS_PROP_LETTER_SPACING:
01950     case CSS_PROP_WORD_SPACING:
01951     {
01952     int width = 0;
01953         if(value->cssValueType() == CSSValue::CSS_INHERIT)
01954         {
01955             if(!parentNode) return;
01956             switch(prop->m_id)
01957             {
01958             case CSS_PROP_MARKER_OFFSET:
01959                 // ###
01960                 return;
01961             case CSS_PROP_LETTER_SPACING:
01962                 width = parentStyle->letterSpacing(); break;
01963             case CSS_PROP_WORD_SPACING:
01964                 width = parentStyle->wordSpacing(); break;
01965             default:
01966                 return;
01967             }
01968         } else {
01969         if(!primitiveValue) return;
01970         width = primitiveValue->computeLength(style, paintDeviceMetrics);
01971     }
01972         switch(prop->m_id)
01973         {
01974         case CSS_PROP_LETTER_SPACING:
01975             style->setLetterSpacing(width);
01976             break;
01977         case CSS_PROP_WORD_SPACING:
01978             style->setWordSpacing(width);
01979             break;
01980             // ### needs the definitions in renderstyle
01981         case CSS_PROP_MARKER_OFFSET:
01982         default: break;
01983         }
01984         return;
01985     }
01986 
01987 // length, percent
01988     case CSS_PROP_MAX_WIDTH:
01989         // +none +inherit
01990         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
01991             apply = true;
01992     case CSS_PROP_TOP:
01993     case CSS_PROP_LEFT:
01994     case CSS_PROP_RIGHT:
01995         // http://www.w3.org/Style/css2-updates/REC-CSS2-19980512-errata
01996         // introduces static-position value for top, left & right
01997         if(prop->m_id != CSS_PROP_MAX_WIDTH && primitiveValue &&
01998            primitiveValue->getIdent() == CSS_VAL_STATIC_POSITION)
01999         {
02000             //kdDebug( 6080 ) << "found value=static-position" << endl;
02001             l = Length ( 0, Static );
02002             apply = true;
02003         }
02004     case CSS_PROP_BOTTOM:
02005     case CSS_PROP_WIDTH:
02006     case CSS_PROP_MIN_WIDTH:
02007     case CSS_PROP_MARGIN_TOP:
02008     case CSS_PROP_MARGIN_RIGHT:
02009     case CSS_PROP_MARGIN_BOTTOM:
02010     case CSS_PROP_MARGIN_LEFT:
02011         // +inherit +auto
02012         if(prop->m_id != CSS_PROP_MAX_WIDTH && primitiveValue &&
02013            primitiveValue->getIdent() == CSS_VAL_AUTO)
02014         {
02015             //kdDebug( 6080 ) << "found value=auto" << endl;
02016             apply = true;
02017         }
02018     case CSS_PROP_PADDING_TOP:
02019     case CSS_PROP_PADDING_RIGHT:
02020     case CSS_PROP_PADDING_BOTTOM:
02021     case CSS_PROP_PADDING_LEFT:
02022     case CSS_PROP_TEXT_INDENT:
02023         // +inherit
02024     {
02025         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
02026             if(!parentNode) return;
02027         apply = true;
02028             switch(prop->m_id)
02029                 {
02030                 case CSS_PROP_MAX_WIDTH:
02031                     l = parentStyle->maxWidth(); break;
02032                 case CSS_PROP_BOTTOM:
02033                     l = parentStyle->bottom(); break;
02034                 case CSS_PROP_TOP:
02035                     l = parentStyle->top(); break;
02036                 case CSS_PROP_LEFT:
02037                     l = parentStyle->left(); break;
02038                 case CSS_PROP_RIGHT:
02039                     l = parentStyle->right(); break;
02040                 case CSS_PROP_WIDTH:
02041                     l = parentStyle->width(); break;
02042                 case CSS_PROP_MIN_WIDTH:
02043                     l = parentStyle->minWidth(); break;
02044                 case CSS_PROP_PADDING_TOP:
02045                     l = parentStyle->paddingTop(); break;
02046                 case CSS_PROP_PADDING_RIGHT:
02047                     l = parentStyle->paddingRight(); break;
02048                 case CSS_PROP_PADDING_BOTTOM:
02049                     l = parentStyle->paddingBottom(); break;
02050                 case CSS_PROP_PADDING_LEFT:
02051                     l = parentStyle->paddingLeft(); break;
02052                 case CSS_PROP_MARGIN_TOP:
02053                     l = parentStyle->marginTop(); break;
02054                 case CSS_PROP_MARGIN_RIGHT:
02055                     l = parentStyle->marginRight(); break;
02056                 case CSS_PROP_MARGIN_BOTTOM:
02057                     l = parentStyle->marginBottom(); break;
02058                 case CSS_PROP_MARGIN_LEFT:
02059                     l = parentStyle->marginLeft(); break;
02060                 case CSS_PROP_TEXT_INDENT:
02061                     l = parentStyle->textIndent(); break;
02062                 default:
02063                     return;
02064                 }
02065         } else if(primitiveValue && !apply) {
02066             int type = primitiveValue->primitiveType();
02067             if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02068                 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02069             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02070                 l = Length((int)primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02071         else if (type == CSSPrimitiveValue::CSS_HTML_RELATIVE)
02072         l = Length(int(primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_HTML_RELATIVE)), Relative);
02073             else
02074                 return;
02075             apply = true;
02076         }
02077         if(!apply) return;
02078         switch(prop->m_id)
02079             {
02080             case CSS_PROP_MAX_WIDTH:
02081                 style->setMaxWidth(l); break;
02082             case CSS_PROP_BOTTOM:
02083                 style->setBottom(l); break;
02084             case CSS_PROP_TOP:
02085                 style->setTop(l); break;
02086             case CSS_PROP_LEFT:
02087                 style->setLeft(l); break;
02088             case CSS_PROP_RIGHT:
02089                 style->setRight(l); break;
02090             case CSS_PROP_WIDTH:
02091                 style->setWidth(l); break;
02092             case CSS_PROP_MIN_WIDTH:
02093                 style->setMinWidth(l); break;
02094             case CSS_PROP_PADDING_TOP:
02095                 style->setPaddingTop(l); break;
02096             case CSS_PROP_PADDING_RIGHT:
02097                 style->setPaddingRight(l); break;
02098             case CSS_PROP_PADDING_BOTTOM:
02099                 style->setPaddingBottom(l); break;
02100             case CSS_PROP_PADDING_LEFT:
02101                 style->setPaddingLeft(l); break;
02102             case CSS_PROP_MARGIN_TOP:
02103                 style->setMarginTop(l); break;
02104             case CSS_PROP_MARGIN_RIGHT:
02105                 style->setMarginRight(l); break;
02106             case CSS_PROP_MARGIN_BOTTOM:
02107                 style->setMarginBottom(l); break;
02108             case CSS_PROP_MARGIN_LEFT:
02109                 style->setMarginLeft(l); break;
02110             case CSS_PROP_TEXT_INDENT:
02111                 style->setTextIndent(l); break;
02112             default: break;
02113             }
02114         return;
02115     }
02116 
02117     case CSS_PROP_MAX_HEIGHT:
02118         // +inherit +none !can be calculted directly!
02119         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
02120             apply = true;
02121     case CSS_PROP_HEIGHT:
02122     case CSS_PROP_MIN_HEIGHT:
02123         // +inherit +auto !can be calculted directly!
02124         if(!prop->m_id == CSS_PROP_MAX_HEIGHT && primitiveValue &&
02125            primitiveValue->getIdent() == CSS_VAL_AUTO)
02126             apply = true;
02127         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02128         {
02129             if(!parentNode) return;
02130         apply = true;
02131             switch(prop->m_id)
02132                 {
02133                 case CSS_PROP_MAX_HEIGHT:
02134                     l = parentStyle->maxHeight(); break;
02135                 case CSS_PROP_HEIGHT:
02136                     l = parentStyle->height(); break;
02137                 case CSS_PROP_MIN_HEIGHT:
02138                     l = parentStyle->minHeight(); break;
02139                 default:
02140                     return;
02141                 }
02142         }
02143         if(primitiveValue && !apply)
02144         {
02145             int type = primitiveValue->primitiveType();
02146             if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02147                 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02148             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02149             {
02150                 // ### compute from parents height!!!
02151                 l = Length((int)primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02152             }
02153             else
02154                 return;
02155             apply = true;
02156         }
02157         if(!apply) return;
02158         switch(prop->m_id)
02159         {
02160         case CSS_PROP_MAX_HEIGHT:
02161             style->setMaxHeight(l); break;
02162         case CSS_PROP_HEIGHT:
02163             style->setHeight(l); break;
02164         case CSS_PROP_MIN_HEIGHT:
02165             style->setMinHeight(l); break;
02166         default:
02167             return;
02168         }
02169         return;
02170 
02171         break;
02172 
02173     case CSS_PROP_VERTICAL_ALIGN:
02174         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02175         {
02176             if(!parentNode) return;
02177             style->setVerticalAlign(parentStyle->verticalAlign());
02178             return;
02179         }
02180         if(!primitiveValue) return;
02181         if(primitiveValue->getIdent()) {
02182 
02183       khtml::EVerticalAlign align;
02184 
02185       switch(primitiveValue->getIdent())
02186         {
02187         case CSS_VAL_TOP:
02188             align = TOP; break;
02189         case CSS_VAL_BOTTOM:
02190             align = BOTTOM; break;
02191         case CSS_VAL_MIDDLE:
02192             align = MIDDLE; break;
02193         case CSS_VAL_BASELINE:
02194             align = BASELINE; break;
02195         case CSS_VAL_TEXT_BOTTOM:
02196             align = TEXT_BOTTOM; break;
02197         case CSS_VAL_TEXT_TOP:
02198             align = TEXT_TOP; break;
02199         case CSS_VAL_SUB:
02200             align = SUB; break;
02201         case CSS_VAL_SUPER:
02202             align = SUPER; break;
02203         case CSS_VAL__KONQ_BASELINE_MIDDLE:
02204             align = BASELINE_MIDDLE; break;
02205         default:
02206             return;
02207         }
02208       style->setVerticalAlign(align);
02209       return;
02210         } else {
02211       int type = primitiveValue->primitiveType();
02212       Length l;
02213       if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02214         l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed );
02215       else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02216         l = Length( int( primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE) ), Percent );
02217 
02218       style->setVerticalAlign( LENGTH );
02219       style->setVerticalAlignLength( l );
02220     }
02221         break;
02222 
02223     case CSS_PROP_FONT_SIZE:
02224     {
02225         FontDef fontDef = style->htmlFont().fontDef;
02226         int oldSize;
02227         int size = 0;
02228 
02229         float toPix = paintDeviceMetrics->logicalDpiY()/72.;
02230         if (toPix  < 96./72.) toPix = 96./72.;
02231 
02232         int minFontSize = int(settings->minFontSize() * toPix);
02233 
02234         if(parentNode) {
02235             oldSize = parentStyle->font().pixelSize();
02236         } else
02237             oldSize = m_fontSizes[3];
02238 
02239         if(value->cssValueType() == CSSValue::CSS_INHERIT) {
02240             size = oldSize;
02241         } else if(primitiveValue->getIdent()) {
02242             switch(primitiveValue->getIdent())
02243             {
02244             case CSS_VAL_XX_SMALL: size = int( m_fontSizes[0] ); break;
02245             case CSS_VAL_X_SMALL:  size = int( m_fontSizes[1] ); break;
02246             case CSS_VAL_SMALL:    size = int( m_fontSizes[2] ); break;
02247             case CSS_VAL_MEDIUM:   size = int( m_fontSizes[3] ); break;
02248             case CSS_VAL_LARGE:    size = int( m_fontSizes[4] ); break;
02249             case CSS_VAL_X_LARGE:  size = int( m_fontSizes[5] ); break;
02250             case CSS_VAL_XX_LARGE: size = int( m_fontSizes[6] ); break;
02251             case CSS_VAL__KONQ_XXX_LARGE:  size = ( m_fontSizes[6]*5 )/3; break;
02252             case CSS_VAL_LARGER:
02253                 // ### use the next bigger standardSize!!!
02254                 size = ( oldSize * 5 ) / 4;
02255                 break;
02256             case CSS_VAL_SMALLER:
02257                 size = ( oldSize * 4 ) / 5;
02258                 break;
02259             default:
02260                 return;
02261             }
02262 
02263         } else {
02264             int type = primitiveValue->primitiveType();
02265             if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) {
02266                 if (!khtml::printpainter && element && element->getDocument()->view())
02267                     size = int( primitiveValue->computeLengthFloat(parentStyle, paintDeviceMetrics) *
02268                                 element->getDocument()->view()->part()->zoomFactor() ) / 100;
02269                 else size = int( primitiveValue->computeLengthFloat(parentStyle, paintDeviceMetrics) );
02270             }
02271             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02272                 size = int(primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE)
02273                         * parentStyle->font().pixelSize()) / 100;
02274             else
02275                 return;
02276 
02277         }
02278 
02279         if(size < 1) return;
02280 
02281         // we never want to get smaller than the minimum font size to keep fonts readable
02282         if(size < minFontSize ) size = minFontSize;
02283 
02284         //kdDebug( 6080 ) << "computed raw font size: " << size << endl;
02285 
02286     fontDef.size = size;
02287         if (style->setFontDef( fontDef ))
02288     fontDirty = true;
02289         return;
02290     }
02291 
02292 // angle
02293 //    case CSS_PROP_ELEVATION:
02294 
02295 // number
02296 //     case CSS_PROP_FONT_SIZE_ADJUST:
02297 //     case CSS_PROP_ORPHANS:
02298 //     case CSS_PROP_PITCH_RANGE:
02299 //     case CSS_PROP_RICHNESS:
02300 //     case CSS_PROP_SPEECH_RATE:
02301 //     case CSS_PROP_STRESS:
02302 //     case CSS_PROP_WIDOWS:
02303         break;
02304     case CSS_PROP_Z_INDEX:
02305     {
02306     int z_index = 0;
02307         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02308        {
02309             if(!parentNode) return;
02310             z_index = parentStyle->zIndex();
02311         } else {
02312             if(!primitiveValue ||
02313                primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
02314                 return;
02315         z_index = (int)primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_NUMBER);
02316     }
02317         style->setZIndex( z_index );
02318         return;
02319     }
02320 
02321 // length, percent, number
02322     case CSS_PROP_LINE_HEIGHT:
02323     {
02324         Length lineHeight;
02325         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02326         {
02327             if(!parentNode) return;
02328             lineHeight = parentStyle->lineHeight();
02329         } else {
02330             if(!primitiveValue) return;
02331             int type = primitiveValue->primitiveType();
02332             if(primitiveValue->getIdent() == CSS_VAL_NORMAL)
02333                 lineHeight = Length( -100, Percent );
02334             else if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02335                 lineHeight = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02336             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02337                 lineHeight = Length( ( style->font().pixelSize() * int(primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE)) ) / 100, Fixed );
02338             else if(type == CSSPrimitiveValue::CSS_NUMBER)
02339                 lineHeight = Length(int(primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_NUMBER)*100), Percent);
02340             else
02341                 return;
02342     }
02343         style->setLineHeight(lineHeight);
02344         return;
02345     }
02346 
02347 // number, percent
02348 //    case CSS_PROP_VOLUME:
02349 
02350 // frequency
02351 //    case CSS_PROP_PITCH:
02352 //        break;
02353 
02354 // string
02355     case CSS_PROP_TEXT_ALIGN:
02356     {
02357         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02358         {
02359             if(!parentNode) return;
02360             style->setTextAlign(parentStyle->textAlign());
02361             return;
02362         }
02363         if(!primitiveValue) return;
02364         if(primitiveValue->getIdent())
02365             style->setTextAlign( (ETextAlign) (primitiveValue->getIdent() - CSS_VAL__KONQ_AUTO) );
02366     return;
02367     }
02368 
02369 // rect
02370     case CSS_PROP_CLIP:
02371     {
02372     Length top;
02373     Length right;
02374     Length bottom;
02375     Length left;
02376     if ( value->cssValueType() == CSSValue::CSS_INHERIT ) {
02377         top = parentStyle->clipTop();
02378         right = parentStyle->clipRight();
02379         bottom = parentStyle->clipBottom();
02380         left = parentStyle->clipLeft();
02381     } else if ( !primitiveValue ) {
02382         break;
02383     } else if ( primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RECT ) {
02384         RectImpl *rect = primitiveValue->getRectValue();
02385         if ( !rect )
02386         break;
02387         top = convertToLength( rect->top(), style, paintDeviceMetrics );
02388         right = convertToLength( rect->right(), style, paintDeviceMetrics );
02389         bottom = convertToLength( rect->bottom(), style, paintDeviceMetrics );
02390         left = convertToLength( rect->left(), style, paintDeviceMetrics );
02391 
02392     } else if ( primitiveValue->getIdent() != CSS_VAL_AUTO ) {
02393         break;
02394     }
02395 //  qDebug("setting clip top to %d", top.value );
02396 //  qDebug("setting clip right to %d", right.value );
02397 //  qDebug("setting clip bottom to %d", bottom.value );
02398 //  qDebug("setting clip left to %d", left.value );
02399     style->setClip( top, right, bottom, left );
02400     style->setClipSpecified( true );
02401         // rect, ident
02402         break;
02403     }
02404 
02405 // lists
02406     case CSS_PROP_CONTENT:
02407         // list of string, uri, counter, attr, i
02408     {
02409         if (!(style->styleType()==RenderStyle::BEFORE ||
02410                 style->styleType()==RenderStyle::AFTER))
02411             break;
02412 
02413         if(!value->isValueList()) return;
02414         CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
02415         int len = list->length();
02416 
02417         for(int i = 0; i < len; i++) {
02418             CSSValueImpl *item = list->item(i);
02419             if(!item->isPrimitiveValue()) continue;
02420             CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item);
02421             if(val->primitiveType()==CSSPrimitiveValue::CSS_STRING)
02422             {
02423                 style->setContent(val->getStringValue());
02424             }
02425             else if (val->primitiveType()==CSSPrimitiveValue::CSS_URI)
02426             {
02427                 CSSImageValueImpl *image = static_cast<CSSImageValueImpl *>(val);
02428                 style->setContent(image->image());
02429             }
02430 
02431         }
02432         break;
02433     }
02434 
02435     case CSS_PROP_COUNTER_INCREMENT:
02436         // list of CSS2CounterIncrement
02437     case CSS_PROP_COUNTER_RESET:
02438         // list of CSS2CounterReset
02439         break;
02440     case CSS_PROP_FONT_FAMILY:
02441         // list of strings and ids
02442     {
02443         if(!value->isValueList()) return;
02444     FontDef fontDef = style->htmlFont().fontDef;
02445         CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
02446         int len = list->length();
02447     QString family;
02448         for(int i = 0; i < len; i++) {
02449             CSSValueImpl *item = list->item(i);
02450             if(!item->isPrimitiveValue()) continue;
02451             CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item);
02452             if(!val->primitiveType() == CSSPrimitiveValue::CSS_STRING) return;
02453             QString face = static_cast<FontFamilyValueImpl *>(val)->fontName();
02454         if ( !face.isNull() || face.isEmpty() ) {
02455         if(face == "serif") {
02456             face = settings->serifFontName();
02457         }
02458         else if(face == "sans-serif") {
02459             face = settings->sansSerifFontName();
02460         }
02461         else if( face == "cursive") {
02462             face = settings->cursiveFontName();
02463         }
02464         else if( face == "fantasy") {
02465             face = settings->fantasyFontName();
02466         }
02467         else if( face == "monospace") {
02468             face = settings->fixedFontName();
02469         }
02470         else if( face == "konq_default") {
02471             face = settings->stdFontName();
02472         }
02473         if ( !face.isEmpty() ) {
02474             fontDef.family = face;
02475             if (style->setFontDef( fontDef ))
02476             fontDirty = true;
02477         }
02478                 return;
02479         }
02480         }
02481         break;
02482     }
02483     case CSS_PROP_QUOTES:
02484         // list of strings or i
02485     case CSS_PROP_SIZE:
02486         // ### look up
02487       break;
02488     case CSS_PROP_TEXT_DECORATION:
02489         // list of ident
02490         // ### no list at the moment
02491     {
02492         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02493         {
02494             if(!parentNode) return;
02495             style->setTextDecoration(parentStyle->textDecoration());
02496             style->setTextDecorationColor(parentStyle->textDecorationColor());
02497             return;
02498         }
02499         int t = TDNONE;
02500         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) {
02501         // do nothing
02502     } else {
02503         if(!value->isValueList()) return;
02504         CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
02505         int len = list->length();
02506         for(int i = 0; i < len; i++)
02507         {
02508         CSSValueImpl *item = list->item(i);
02509         if(!item->isPrimitiveValue()) continue;
02510         primitiveValue = static_cast<CSSPrimitiveValueImpl *>(item);
02511         switch(primitiveValue->getIdent())
02512         {
02513             case CSS_VAL_NONE:
02514             t = TDNONE; break;
02515             case CSS_VAL_UNDERLINE:
02516             t |= UNDERLINE; break;
02517             case CSS_VAL_OVERLINE:
02518             t |= OVERLINE; break;
02519             case CSS_VAL_LINE_THROUGH:
02520             t |= LINE_THROUGH; break;
02521             case CSS_VAL_BLINK:
02522             t |= BLINK; break;
02523             default:
02524             return;
02525         }
02526         }
02527         }
02528     style->setTextDecoration(t);
02529     style->setTextDecorationColor(style->color());
02530         break;
02531     }
02532     case CSS_PROP__KONQ_FLOW_MODE:
02533         if(value->cssValueType() == CSSValue::CSS_INHERIT)
02534         {
02535             if(!parentNode) return;
02536             style->setFlowAroundFloats(parentStyle->flowAroundFloats());
02537             return;
02538         }
02539         if(!primitiveValue) return;
02540         if(primitiveValue->getIdent())
02541         {
02542             style->setFlowAroundFloats( primitiveValue->getIdent() == CSS_VAL__KONQ_AROUND_FLOATS );
02543             return;
02544         }
02545         break;
02546 //     case CSS_PROP_VOICE_FAMILY:
02547 //         // list of strings and i
02548 //         break;
02549 
02550 // shorthand properties
02551     case CSS_PROP_BACKGROUND:
02552         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02553         style->setBackgroundColor(parentStyle->backgroundColor());
02554         style->setBackgroundImage(parentStyle->backgroundImage());
02555         style->setBackgroundRepeat(parentStyle->backgroundRepeat());
02556         style->setBackgroundAttachment(parentStyle->backgroundAttachment());
02557 //      style->setBackgroundPosition(parentStyle->backgroundPosition());
02558 
02559         break;
02560     case CSS_PROP_BORDER_COLOR:
02561         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_TRANSPARENT)
02562         {
02563             style->setBorderTopColor(QColor());
02564             style->setBorderBottomColor(QColor());
02565             style->setBorderLeftColor(QColor());
02566             style->setBorderRightColor(QColor());
02567             return;
02568         }
02569     case CSS_PROP_BORDER:
02570     case CSS_PROP_BORDER_STYLE:
02571     case CSS_PROP_BORDER_WIDTH:
02572         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02573 
02574         if(prop->m_id == CSS_PROP_BORDER || prop->m_id == CSS_PROP_BORDER_COLOR)
02575         {
02576             style->setBorderTopColor(parentStyle->borderTopColor());
02577             style->setBorderBottomColor(parentStyle->borderBottomColor());
02578             style->setBorderLeftColor(parentStyle->borderLeftColor());
02579             style->setBorderRightColor(parentStyle->borderRightColor());
02580         }
02581         if(prop->m_id == CSS_PROP_BORDER || prop->m_id == CSS_PROP_BORDER_STYLE)
02582         {
02583             style->setBorderTopStyle(parentStyle->borderTopStyle());
02584             style->setBorderBottomStyle(parentStyle->borderBottomStyle());
02585             style->setBorderLeftStyle(parentStyle->borderLeftStyle());
02586             style->setBorderRightStyle(parentStyle->borderRightStyle());
02587         }
02588         if(prop->m_id == CSS_PROP_BORDER || prop->m_id == CSS_PROP_BORDER_WIDTH)
02589         {
02590             style->setBorderTopWidth(parentStyle->borderTopWidth());
02591             style->setBorderBottomWidth(parentStyle->borderBottomWidth());
02592             style->setBorderLeftWidth(parentStyle->borderLeftWidth());
02593             style->setBorderRightWidth(parentStyle->borderRightWidth());
02594         }
02595         return;
02596     case CSS_PROP_BORDER_TOP:
02597         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02598         style->setBorderTopColor(parentStyle->borderTopColor());
02599         style->setBorderTopStyle(parentStyle->borderTopStyle());
02600         style->setBorderTopWidth(parentStyle->borderTopWidth());
02601         return;
02602     case CSS_PROP_BORDER_RIGHT:
02603         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02604         style->setBorderRightColor(parentStyle->borderRightColor());
02605         style->setBorderRightStyle(parentStyle->borderRightStyle());
02606         style->setBorderRightWidth(parentStyle->borderRightWidth());
02607         return;
02608     case CSS_PROP_BORDER_BOTTOM:
02609         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02610         style->setBorderBottomColor(parentStyle->borderBottomColor());
02611         style->setBorderBottomStyle(parentStyle->borderBottomStyle());
02612         style->setBorderBottomWidth(parentStyle->borderBottomWidth());
02613         return;
02614     case CSS_PROP_BORDER_LEFT:
02615         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02616         style->setBorderLeftColor(parentStyle->borderLeftColor());
02617         style->setBorderLeftStyle(parentStyle->borderLeftStyle());
02618         style->setBorderLeftWidth(parentStyle->borderLeftWidth());
02619         return;
02620     case CSS_PROP_MARGIN:
02621         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02622         style->setMarginTop(parentStyle->marginTop());
02623         style->setMarginBottom(parentStyle->marginBottom());
02624         style->setMarginLeft(parentStyle->marginLeft());
02625         style->setMarginRight(parentStyle->marginRight());
02626         return;
02627     case CSS_PROP_PADDING:
02628         if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02629         style->setPaddingTop(parentStyle->paddingTop());
02630         style->setPaddingBottom(parentStyle->paddingBottom());
02631         style->setPaddingLeft(parentStyle->paddingLeft());
02632         style->setPaddingRight(parentStyle->paddingRight());
02633         return;
02634 
02635 //     case CSS_PROP_CUE:
02636     case CSS_PROP_FONT:
02637     case CSS_PROP_LIST_STYLE:
02638     case CSS_PROP_OUTLINE:
02639 //    case CSS_PROP_PAUSE:
02640         break;
02641     default:
02642         return;
02643     }
02644 }
02645 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:16:32 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001