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