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