# khtml Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# 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

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:33:35 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001