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