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