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)
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
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
00119
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
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
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
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
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
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
00287
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
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
00329
00330
00331
00332
00333
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
00347
00348
00349
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
00358
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
00371 for (unsigned int i = 0; i < numPseudoProps; ++i) {
00372 if ( fontDirty && pseudoProps[i]->priority >= (1 << 30) ) {
00373
00374
00375
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
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
00452
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
00482 subject = true;
00483
00484
00485
00486 bool single = false;
00487 if ( sel->tag == -1 )
00488 single = true;
00489
00490
00491 if(!checkOneSelector(sel, e)) return;
00492
00493
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
00539 ElementImpl *elem = static_cast<ElementImpl *>(n);
00540
00541 if ( dynamicPseudo != RenderStyle::NOPSEUDO ) {
00542 qDebug("failing, dynamicPseudo: %d", dynamicPseudo);
00543 return;
00544 }
00545 if(!checkOneSelector(sel, elem)) return;
00546
00547 break;
00548 }
00549 }
00550 relation = sel->relation;
00551 }
00552
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
00564
00565 return;
00566 }
00567
00568
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
00577 if (prev < 0 || (prev > 3 && path.findRev("://", prev-1) == prev-2))
00578 path.remove( pos, 3);
00579 else
00580
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
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
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
00622
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;
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
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
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
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
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
00700 if(str.string().find(selStr.string(), 0, strictParsing) != 0) return false;
00701
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
00714
00715 QConstString cstr( sel->value.implementation()->s, sel->value.implementation()->l );
00716 const QString& value = cstr.string();
00717
00718 switch( *( value.unicode() ) ) {
00719 case 'f':
00720 if(value == "first-child") {
00721
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
00759
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
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
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
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
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
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
00952
00953 if( sheet->media() && !sheet->media()->contains( medium ) )
00954 return;
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
00970 }
00971 }
00972 else if(item->isImportRule())
00973 {
00974 CSSImportRuleImpl *import = static_cast<CSSImportRuleImpl *>(item);
00975
00976
00977
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
00991
00992
00993
00994 if( ( !r->media() || r->media()->contains( medium ) ) && rules)
00995 {
00996
00997
00998
00999 for( unsigned j = 0; j < rules->length(); j++ )
01000 {
01001
01002
01003 CSSRuleImpl *childItem = rules->item( j );
01004 if( childItem->isStyleRule() )
01005 {
01006
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
01021
01022 }
01023 }
01024 }
01025 else
01026 {
01027
01028
01029 }
01030 }
01031
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
01052
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
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
01095
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
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
01138
01139 CSSPrimitiveValueImpl *primitiveValue = 0;
01140 if(value->isPrimitiveValue()) primitiveValue = static_cast<CSSPrimitiveValueImpl *>(value);
01141
01142 Length l;
01143 bool apply = false;
01144
01145
01146
01147 switch(prop->m_id)
01148 {
01149
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
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
01344 return;
01345 } else {
01346 d = EDisplay(primitiveValue->getIdent() - CSS_VAL_INLINE);
01347 }
01348
01349 style->setDisplay(d);
01350
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:
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
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
01446
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
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) {
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
01538
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
01573
01574
01575
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
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
01683
01684
01685 case CSS_PROP_BACKGROUND_POSITION:
01686
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
01725 case CSS_PROP_CURSOR:
01726
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
01736
01737
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
01746 case CSS_PROP_TEXT_DECORATION_COLOR:
01747
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
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
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
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
01857 break;
01858 }
01859
01860
01861
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
01875 break;
01876 }
01877
01878
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
01981 case CSS_PROP_MARKER_OFFSET:
01982 default: break;
01983 }
01984 return;
01985 }
01986
01987
01988 case CSS_PROP_MAX_WIDTH:
01989
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
01996
01997 if(prop->m_id != CSS_PROP_MAX_WIDTH && primitiveValue &&
01998 primitiveValue->getIdent() == CSS_VAL_STATIC_POSITION)
01999 {
02000
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
02012 if(prop->m_id != CSS_PROP_MAX_WIDTH && primitiveValue &&
02013 primitiveValue->getIdent() == CSS_VAL_AUTO)
02014 {
02015
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
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
02119 if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
02120 apply = true;
02121 case CSS_PROP_HEIGHT:
02122 case CSS_PROP_MIN_HEIGHT:
02123
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
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
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
02282 if(size < minFontSize ) size = minFontSize;
02283
02284
02285
02286 fontDef.size = size;
02287 if (style->setFontDef( fontDef ))
02288 fontDirty = true;
02289 return;
02290 }
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
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
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
02348
02349
02350
02351
02352
02353
02354
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
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
02396
02397
02398
02399 style->setClip( top, right, bottom, left );
02400 style->setClipSpecified( true );
02401
02402 break;
02403 }
02404
02405
02406 case CSS_PROP_CONTENT:
02407
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
02437 case CSS_PROP_COUNTER_RESET:
02438
02439 break;
02440 case CSS_PROP_FONT_FAMILY:
02441
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
02485 case CSS_PROP_SIZE:
02486
02487 break;
02488 case CSS_PROP_TEXT_DECORATION:
02489
02490
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
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
02547
02548
02549
02550
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
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
02636 case CSS_PROP_FONT:
02637 case CSS_PROP_LIST_STYLE:
02638 case CSS_PROP_OUTLINE:
02639
02640 break;
02641 default:
02642 return;
02643 }
02644 }
02645