| # khtml Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# cssstyleselector.cpp

    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) // this may be null, not everyone uses khtmlview (Niko)
    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     // add stylesheets from document
    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     //kdDebug( 6080 ) << "number of style sheets in document " << authorStyleSheets.count() << endl;
    00163     //kdDebug( 6080 ) << "CSSStyleSelector: author style has " << authorStyle->count() << " elements"<< endl;
    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     //kdDebug() << "CSSStyleSelector::CSSStyleSelector encoded url " << encodedurl.path << endl;
    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     // Collect only strict-mode rules.
    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     // Collect only quirks-mode rules.
    00272     s_defaultQuirksStyle = new CSSStyleSelectorList();
    00273     s_defaultQuirksStyle->append( s_quirksSheet, "screen" );
    00274     }
    00275
    00276     //kdDebug() << "CSSStyleSelector: default style has " << defaultStyle->count() << " elements"<< endl;
    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     // nice leak, but best we can do right now. hopefully its only rare.
    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     // We don't want to scale the settings by the dpi.
    00314     const float toPix = 1;
    00315 #else
    00316     Q_UNUSED( isFixed );
    00317
    00318     // ### get rid of float / double
    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         // ## depending on something / configurable ?
    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         //kdDebug( 6080 ) << "index: " << i << " factor: " << factors[i] << " font pix size: " << int(KMAX( mediumFontSize*factor +.5f, minFontSize)) << endl;
    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     // set some variables we will need
    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     // try to sort out most style rules as early as possible.
    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 //      qDebug("adding property" );
    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     // inline style declarations, after all others. non css hints
    00447     // count as author rules, and come before all other style sheets, see hack in append()
    00448     numPropsToApply = addInlineDeclarations( e, e->m_styleDecls, numPropsToApply );
    00449
    00450 //     qDebug( "styleForElement( %s )", e->tagName().string().latin1() );
    00451 //     qDebug( "%d selectors, %d checked,  %d match,  %d properties ( of %d )",
    00452 //      selectors_size, schecked, smatch, numPropsToApply, properties_size );
    00453
    00454     bubbleSort( propsToApply, propsToApply+numPropsToApply-1 );
    00455     bubbleSort( pseudoProps, pseudoProps+numPseudoProps-1 );
    00456
    00457     // we can't apply style rules without a view() and a part. This
    00458     // tends to happen on delayed destruction of widget Renderobjects
    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             // we are past the font properties, time to update to the
    00467             // correct font
    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 //      if (prop->m_id == CSS_PROP__KONQ_USER_INPUT) kdDebug(6080) << "El: "<<e->nodeName().string() << " user-input: "<<((CSSPrimitiveValueImpl *)prop->value())->getIdent() << endl;
    00476 //      if (prop->m_id == CSS_PROP_TEXT_TRANSFORM) kdDebug(6080) << "El: "<<e->nodeName().string() << endl;
    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         // Clean up our style object's display and text decorations (among other fixups).
    00488         adjustRenderStyle(style, e);
    00489
    00490         if ( numPseudoProps ) {
    00491         fontDirty = false;
    00492             //qDebug("%d applying %d pseudo props", e->cssTagId(), pseudoProps->count() );
    00493             for (unsigned int i = 0; i < numPseudoProps; ++i) {
    00494         if ( fontDirty && pseudoProps[i]->priority >= (1 << 30) ) {
    00495             // we are past the font properties, time to update to the
    00496             // correct font
    00497             //We have to do this for all pseudo styles
    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     // Now adjust all our pseudo-styles.
    00538     RenderStyle *pseudoStyle = style->pseudoStyle;
    00539     while (pseudoStyle) {
    00540         adjustRenderStyle(pseudoStyle, 0);
    00541         pseudoStyle = pseudoStyle->pseudoStyle;
    00542     }
    00543
    00544     // Now return the style.
    00545     return style;
    00546 }
    00547
    00548 void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, DOM::ElementImpl *e)
    00549 {
    00550      // Cache our original display.
    00551      style->setOriginalDisplay(style->display());
    00552
    00553     if (style->display() != NONE) {
    00554         // If we have a <td> that specifies a float property, in quirks mode we just drop the float
    00555         // property.
    00556         // Sites also commonly use display:inline/block on <td>s and <table>s.  In quirks mode we force
    00557         // these tags to retain their display types.
    00558         if (!strictParsing && e) {
    00559             if (e->id() == ID_TD) {
    00560                 style->setDisplay(TABLE_CELL);
    00561                 style->setFloating(FNONE);
    00562             }
    00563 //             else if (e->id() == ID_TABLE)
    00564 //                 style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
    00565         }
    00566
    00567         // Mutate the display to BLOCK or TABLE for certain cases, e.g., if someone attempts to
    00568         // position or float an inline, compact, or run-in.  Cache the original display, since it
    00569         // may be needed for positioned elements that have to compute their static normal flow
    00570         // positions.  We also force inline-level roots to be block-level.
    00571         if (style->display() != BLOCK && style->display() != TABLE /*&& style->display() != BOX*/ &&
    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 //             else if (style->display() == INLINE_BOX)
    00577 //                 style->setDisplay(BOX);
    00578             else if (style->display() == LIST_ITEM) {
    00579                 // It is a WinIE bug that floated list items lose their bullets, so we'll emulate the quirk,
    00580                 // but only in quirks mode.
    00581                 if (!strictParsing && style->floating() != FNONE)
    00582                     style->setDisplay(BLOCK);
    00583             }
    00584             else
    00585                 style->setDisplay(BLOCK);
    00586         }
    00587
    00588         // After performing the display mutation, check table rows.  We do not honor position:relative on
    00589         // table rows. This has been established in CSS2.1 (and caused a crash in containingBlock() on
    00590         // some sites).
    00591         // Likewise, disallow relative positioning on table sections.
    00592         if ( style->position() == RELATIVE && (style->display() > INLINE_TABLE && style->display() < TABLE_COLUMN_GROUP) )
    00593             style->setPosition(STATIC);
    00594     }
    00595
    00596     // Frames and framesets never honor position:relative or position:absolute.  This is necessary to
    00597     // fix a crash where a site tries to position these objects.
    00598     if ( e ) {
    00599         // ignore display: none for <frame>
    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     // Finally update our text decorations in effect, but don't allow text-decoration to percolate through
    00610     // tables, inline blocks, inline tables, or run-ins.
    00611     if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN
    00612         || style->display() == INLINE_BLOCK /*|| style->display() == INLINE_BOX*/)
    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)     // For now only TableCellElement implements the
    00625         addDecls = e->getAdditionalStyleDecls();  // virtual function for shared cell rules.
    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         // give special priority to font-xxx, color properties
    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             // these have to be applied first, because other properties use the computed
    00675             // values of these properties.
    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 // modified version of the one in kurl.cpp
    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         // don't remove the host, i.e. http://foo.org/../foo.html
    00704         if (prev < 0 || (prev > 3 && path.findRev("://", prev-1) == prev-2))
    00705             path.remove( pos, 3);
    00706         else
    00707             // matching directory found ?
    00708             path.remove( prev, pos- prev + 3 );
    00709     }
    00710     pos = 0;
    00711
    00712     // Don't remove "//" from an anchor identifier. -rjw
    00713     // Set refPos to -2 to mean "I haven't looked for the anchor yet".
    00714     // We don't want to waste a function call on the search for the anchor
    00715     // in the vast majority of cases where there is no "//" in the path.
    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     //kdDebug() << "checkPseudoState " << path << endl;
    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     //completeURL( attr.string() );
    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 // a helper function for parsing nth-arguments
    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     // we have the subject part of the selector
    00824     subject = true;
    00825
    00826     // We track whether or not the rule contains only :hover and :active in a simple selector. If
    00827     // so, we can't allow that to apply to every element on the page.  We assume the author intended
    00828     // to apply the rules only to links.
    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     // first selector has to match
    00837     if(!checkOneSelector(sel, e)) return;
    00838
    00839     // check the subselectors
    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         //kdDebug() << "CSSOrderedRule::checkSelector" << endl;
    00902         ElementImpl *elem = static_cast<ElementImpl *>(n);
    00903         // a selector is invalid if something follows :first-xxx
    00904         if ( dynamicPseudo != RenderStyle::NOPSEUDO ) {
    00905         return;
    00906         }
    00907         if(!checkOneSelector(sel, elem)) return;
    00908         //kdDebug() << "CSSOrderedRule::checkSelector: passed" << endl;
    00909         break;
    00910     }
    00911         }
    00912         relation = sel->relation;
    00913     }
    00914
    00915     // disallow *:hover, *:active, and *:hover:active except for links
    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     //qDebug( "selector %d applies", selIndex );
    00935     //selectors[ selIndex ]->print();
    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        // all namespaces would match
    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        // specific namespace selected
    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            // ### fixme: this should allow attributes from all
    00965            // ### namespaces. I'm not 100% sure what the semantics
    00966            // ### should be in this case. Do they all have to match?
    00967            // ### Or should only one of them match. Anyways it might
    00968            // ### be we have to iterate over all namespaces and check
    00969            // ### all of them. For now we just set the namespace to
    00970            // ### 0, so they at least match attributes in the default
    00971            // ### namespace.
    00972            attr_id &= NodeImpl_IdLocalMask;
    00973        }
    00974         DOMString value = e->getAttribute(attr_id);
    00975         if(value.isNull()) return false; // attribute is not set
    00976
    00977         switch(sel->match)
    00978         {
    00979         case CSSSelector::Exact:
    00980             /* attribut values are case insensitive in all HTML modes,
    00981                even in the strict ones */
    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         // There is no list, just a single item.  We can avoid
    01002         // allocing QStrings and just treat this as an exact
    01003         // match check.
    01004         if( (strictParsing && strcmp(sel->value, value) ) ||
    01005             (!strictParsing && strcasecmp(sel->value, value)))
    01006             return false;
    01007         break;
    01008         }
    01009
    01010             // The selector's value can't contain a space, or it's totally bogus.
    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; // We have a match.
    01026                 }
    01027                 ++pos;
    01028             }
    01029             break;
    01030         }
    01031         case CSSSelector::Contain:
    01032         {
    01033             //kdDebug( 6080 ) << "checking for contains match" << endl;
    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             //kdDebug( 6080 ) << "checking for beginswith match" << endl;
    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             //kdDebug( 6080 ) << "checking for endswith match" << endl;
    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             //kdDebug( 6080 ) << "checking for hyphen match" << endl;
    01065             QString str = value.string();
    01066             QString selStr = sel->value.string();
    01067             if(str.length() < selStr.length()) return false;
    01068             // Check if str begins with selStr:
    01069             if(str.find(selStr, 0, strictParsing) != 0) return false;
    01070             // It does. Check for exact match or following '-':
    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         // Pseudo classes:
    01085     case CSSSelector::PseudoEmpty:
    01086             // If e is not closed yet we don't know the number of children
    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         // first-child matches the first child that is an element!
    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             // last-child matches the last child that is an element!
    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             // If both first-child and last-child apply, then only-child applies.
    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         // nth-child matches every (a*n+b)th element!
    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 //                kdDebug(6080) << "NthChild " << count << "=" << sel->string_arg << endl;
    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 //                kdDebug(6080) << "NthLastChild " << count << "=" << sel->string_arg << endl;
    01171                 if (matchNth(count,sel->string_arg.string()))
    01172                     return true;
    01173             }
    01174             break;
    01175         }
    01176     case CSSSelector::PseudoFirstOfType: {
    01177         // first-of-type matches the first element of its type!
    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             // last-child matches the last child that is an element!
    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             // If both first-of-type and last-of-type apply, then only-of-type applies.
    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         // nth-of-type matches every (a*n+b)th element of this type!
    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 //                kdDebug(6080) << "NthOfType " << count << "=" << sel->string_arg << endl;
    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 //                kdDebug(6080) << "NthLastOfType " << count << "=" << sel->string_arg << endl;
    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         // If we're in quirks mode, then hover should never match anchors with no
    01287         // href.  This is important for sites like wsj.com.
    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         // If we're in quirks mode, then :active should never match anchors with no
    01307         // href.
    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 //            kdDebug(6080) << ":lang " << langAttr << "=" << langSel << "?" << endl;
    01327             return langAttr.startsWith(langSel);
    01328         }
    01329         case CSSSelector::PseudoNot: {
    01330             // check the simple selector
    01331             for (CSSSelector* subSel = sel->simpleSelector; subSel;
    01332                  subSel = subSel->tagHistory) {
    01333                 // :not cannot nest.  I don't really know why this is a restriction in CSS3,
    01334                 // but it is, so let's honor it.
    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 //                kdDebug(6080) << ":contains(\"" << selStr << "\")" << " on \"" << s << "\"" << endl;
    01369                 return s.string().contains(selStr);
    01370             }
    01371             break;
    01372         }
    01373     case CSSSelector::PseudoChecked:
    01374     case CSSSelector::PseudoIndeterminate:
    01375         /* not supported for now */
    01376     case CSSSelector::PseudoOther:
    01377         break;
    01378
    01379     // Pseudo-elements:
    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     // ### add the rest of the checks...
    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     // collect all selectors and Properties in lists. Then transfer them to the array for faster lookup.
    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     // presort properties. Should make the sort() calls in styleForElement faster.
    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     // and now the same for the selector map
    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 //                    offset = p-selectors;
    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     // No media implies "all", but if a medialist exists it must
    01576     // contain our current medium
    01577     if( sheet->media() && !sheet->media()->contains( medium ) )
    01578         return; // style sheet not applicable for this medium
    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                 //kdDebug( 6080 ) << "appending StyleRule!" << endl;
    01594             }
    01595         }
    01596         else if(item->isImportRule())
    01597         {
    01598             CSSImportRuleImpl *import = static_cast<CSSImportRuleImpl *>(item);
    01599
    01600             //kdDebug( 6080 ) << "@import: Media: "
    01601             //                << import->media()->mediaText().string() << endl;
    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             //DOMString mediaText = media->mediaText();
    01615             //kdDebug( 6080 ) << "@media: Media: "
    01616             //                << r->media()->mediaText().string() << endl;
    01617
    01618             if( ( !r->media() || r->media()->contains( medium ) ) && rules)
    01619             {
    01620                 // Traverse child elements of the @import rule. Since
    01621                 // many elements are not allowed as child we do not use
    01622                 // a recursive call to append() here
    01623                 for( unsigned j = 0; j < rules->length(); j++ )
    01624                 {
    01625                     //kdDebug( 6080 ) << "*** Rule #" << j << endl;
    01626
    01627                     CSSRuleImpl *childItem = rules->item( j );
    01628                     if( childItem->isStyleRule() )
    01629                     {
    01630                         // It is a StyleRule, so append it to our list
    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                         //kdDebug( 6080 ) << "Ignoring child rule of "
    01645                         //    "ImportRule: rule is not a StyleRule!" << endl;
    01646                     }
    01647                 }   // for rules
    01648             }   // if rules
    01649             else
    01650             {
    01651                 //kdDebug( 6080 ) << "CSSMediaRule not rendered: "
    01652                 //                << "rule empty or wrong medium!" << endl;
    01653             }
    01654         }
    01655         // ### include other rules
    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 //  else
    01676 //      qDebug("merged one selector");
    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         // give special priority to font-xxx, color properties
    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             // these have to be applied first, because other properties use the computed
    01719             // values of these porperties.
    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 // this is mostly boring stuff on how to apply a certain rule to the renderstyle...
    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 // color mapping code
    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 /* Mapping system settings to CSS 2
    01802 * Tried hard to get an appropriate mapping - schlpbch
    01803 */
    01804 static const uiColors uimap[] = {
    01805     // Active window border.
    01806     { CSS_VAL_ACTIVEBORDER, wmgroup, "background", QPalette::Active, QColorGroup::Light },
    01807     // Active window caption.
    01808     { CSS_VAL_ACTIVECAPTION, wmgroup, "background", QPalette::Active, QColorGroup::Text },
    01809         // Text in caption, size box, and scrollbar arrow box.
    01810     { CSS_VAL_CAPTIONTEXT, wmgroup, "activeForeground", QPalette::Active, QColorGroup::Text },
    01811     // Face color for three-dimensional display elements.
    01812     { CSS_VAL_BUTTONFACE, wmgroup, 0, QPalette::Inactive, QColorGroup::Button },
    01813     // Dark shadow for three-dimensional display elements (for edges facing away from the light source).
    01814     { CSS_VAL_BUTTONHIGHLIGHT, wmgroup, 0, QPalette::Inactive, QColorGroup::Light },
    01815     // Shadow color for three-dimensional display elements.
    01816     { CSS_VAL_BUTTONSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Shadow },
    01817     // Text on push buttons.
    01818     { CSS_VAL_BUTTONTEXT, wmgroup, "buttonForeground", QPalette::Inactive, QColorGroup::ButtonText },
    01819     // Dark shadow for three-dimensional display elements.
    01820     { CSS_VAL_THREEDDARKSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Dark },
    01821     // Face color for three-dimensional display elements.
    01822     { CSS_VAL_THREEDFACE, wmgroup, 0, QPalette::Inactive, QColorGroup::Button },
    01823     // Highlight color for three-dimensional display elements.
    01824     { CSS_VAL_THREEDHIGHLIGHT, wmgroup, 0, QPalette::Inactive, QColorGroup::Light },
    01825     // Light color for three-dimensional display elements (for edges facing the light source).
    01826     { CSS_VAL_THREEDLIGHTSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Midlight },
    01827     // Dark shadow for three-dimensional display elements.
    01828     { CSS_VAL_THREEDSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Shadow },
    01829
    01830     // Inactive window border.
    01831     { CSS_VAL_INACTIVEBORDER, wmgroup, "background", QPalette::Disabled, QColorGroup::Background },
    01832     // Inactive window caption.
    01833     { CSS_VAL_INACTIVECAPTION, wmgroup, "inactiveBackground", QPalette::Disabled, QColorGroup::Background },
    01834     // Color of text in an inactive caption.
    01835     { CSS_VAL_INACTIVECAPTIONTEXT, wmgroup, "inactiveForeground", QPalette::Disabled, QColorGroup::Text },
    01836     { CSS_VAL_GRAYTEXT, wmgroup, 0, QPalette::Disabled, QColorGroup::Text },
    01837
    01838     // Menu background
    01839     { CSS_VAL_MENU, generalgroup, "background", QPalette::Inactive, QColorGroup::Background },
    01840     // Text in menus
    01841     { CSS_VAL_MENUTEXT, generalgroup, "foreground", QPalette::Inactive, QColorGroup::Background },
    01842
    01843         // Text of item(s) selected in a control.
    01844     { CSS_VAL_HIGHLIGHT, generalgroup, "selectBackground", QPalette::Inactive, QColorGroup::Background },
    01845
    01846     // Text of item(s) selected in a control.
    01847     { CSS_VAL_HIGHLIGHTTEXT, generalgroup, "selectForeground", QPalette::Inactive, QColorGroup::Background },
    01848
    01849     // Background color of multiple document interface.
    01850     { CSS_VAL_APPWORKSPACE, generalgroup, "background", QPalette::Inactive, QColorGroup::Text },
    01851
    01852     // Scroll bar gray area.
    01853     { CSS_VAL_SCROLLBAR, generalgroup, "background", QPalette::Inactive, QColorGroup::Background },
    01854
    01855     // Window background.
    01856     { CSS_VAL_WINDOW, generalgroup, "windowBackground", QPalette::Inactive, QColorGroup::Background },
    01857     // Window frame.
    01858     { CSS_VAL_WINDOWFRAME, generalgroup, "windowBackground", QPalette::Inactive, QColorGroup::Background },
    01859         // WindowText
    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     // try the regular ones first
    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); // No multi-screen support
    01885         bckgrConfig.setGroup("Desktop0");
    01886         // Desktop background.
    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     // return the nearest bigger/smaller value in scale a, when v is in range.
    01909     // otherwise increase/decrease value using a 1.2 fixed ratio
    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 //      kdDebug( 6080 ) << "applying property " << id << endl;
    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     // What follows is a list that maps the CSS properties into their corresponding front-end
    01944     // RenderStyle values.  Shorthands (e.g. border, background) occur in this list as well and
    01945     // are only hit when mapping "inherit" or "initial" into front-end values.
    01946     switch(id)
    01947     {
    01948 // ident only properties
    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         // only use slow repaints if we actually have a background pixmap
    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:  //Non standart CSS-Value
    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         // ### oblique is the same as italic for the moment...
    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             // ### we just support normal and bold fonts at the moment...
    02185             // setWeight can actually accept values between 0 and 99...
    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         // ### fix parsing of 100-900 values in parser, apply them here
    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) { // important!!
    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); // CSS2.1: "Conforming user agents may map left/right to always."
    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); // CSS2.1: "Conforming user agents may map left/right to always."
    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 //    case CSS_PROP_PAUSE_AFTER:
    02317 //    case CSS_PROP_PAUSE_BEFORE:
    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         // fall through
    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 // colors || inherit
    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         // this property is an extension used to get HTML4 <font> right.
    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             // The border/outline colors will just map to the invalid color |col| above.  This will have the
    02544             // effect of forcing the use of the currentColor when it comes time to draw the borders (and of
    02545             // not painting the background since the color won't be valid).
    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         // ### should be eliminated
    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         //kdDebug( 6080 ) << "applying color " << col.isValid() << endl;
    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             // fall through
    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 // uri || inherit
    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         //kdDebug( 6080 ) << "setting image in style to " << image << endl;
    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         //kdDebug( 6080 ) << "setting image in list to " << image->image() << endl;
    02647         break;
    02648     }
    02649
    02650 // length
    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             // somewhat resemble Mozilla's granularity
    02692             // this makes border-width: 0.5pt borders visible
    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             // ### needs the definitions in renderstyle
    02751         default: break;
    02752         }
    02753         return;
    02754     }
    02755
    02756         // length, percent
    02757     case CSS_PROP_MAX_WIDTH:
    02758         // +none +inherit
    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         // +inherit +auto
    02772         if(id != CSS_PROP_MAX_WIDTH && primitiveValue &&
    02773            primitiveValue->getIdent() == CSS_VAL_AUTO)
    02774         {
    02775             //kdDebug( 6080 ) << "found value=auto" << endl;
    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         // +inherit
    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                 // Handle our quirky margin units if we have them.
    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         // keywords are being used.  Pick the correct default
    02991         // based off the font family.
    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         // we never want to get smaller than the minimum font size to keep fonts readable
    03038         if(size < minFontSize ) size = minFontSize;
    03039
    03040         //kdDebug( 6080 ) << "computed raw font size: " << size << endl;
    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; // Error case.
    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 // length, percent, number
    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             // Scale for the font zoom factor only for types other than "em" and "ex", since those are
    03101             // already based on the font size.
    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 // string
    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 // rect
    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 //  qDebug("setting clip top to %d", top.value );
    03166 //  qDebug("setting clip right to %d", right.value );
    03167 //  qDebug("setting clip bottom to %d", bottom.value );
    03168 //  qDebug("setting clip left to %d", left.value );
    03169     style->setClip(top, right, bottom, left );
    03170     style->setHasClip(hasClip);
    03171         // rect, ident
    03172         break;
    03173     }
    03174
    03175 // lists
    03176     case CSS_PROP_CONTENT:
    03177         // list of string, uri, counter, attr, i
    03178     {
    03179         // FIXME: In CSS3, it will be possible to inherit content.  In CSS2 it is not.  This
    03180         // note is a reminder that eventually "inherit" needs to be supported.
    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                         // no break
    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                         // no break
    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         // list of strings and ids
    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             // set a set of empty quotes
    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         // ### look up
    03357       break;
    03358     case CSS_PROP_TEXT_DECORATION: {
    03359         // list of ident
    03360         HANDLE_INHERIT_AND_INITIAL(textDecoration, TextDecoration)
    03361         int t = RenderStyle::initialTextDecoration();
    03362         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) {
    03363         // do nothing
    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 //      kdDebug() << "UI erm" << endl;
    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 //  kdDebug(6080) << "userInput: " << style->userEdit() << endl;
    03416     return;
    03417     }
    03418
    03419 // shorthand properties
    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()); // Reset to invalid color so currentColor is used instead.
    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             // Line-height can depend on font().pixelSize(), so we have to update the font
    03564             // before we evaluate line-height, e.g., font: 1em/1em.  FIXME: Still not
    03565             // good enough: style="font:1em/1em; font-size:36px" should have a line-height of 36px.
    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     /* CSS3 properties */
    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) { // none
    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; // Error case.
    03656
    03657         // Clamp opacity to the range 0-1
    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); // -1 means repeat forever.
    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); // 500 msec.
    03685                     break;
    03686                 case CSS_VAL_NORMAL:
    03687                     style->setMarqueeSpeed(85); // 85msec. The WinIE default.
    03688                     break;
    03689                 case CSS_VAL_FAST:
    03690                     style->setMarqueeSpeed(10); // 10msec. Super fast.
    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) // For scrollamount support.
    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)); // 1px.
    03710                     break;
    03711                 case CSS_VAL_NORMAL:
    03712                     style->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default.
    03713                     break;
    03714                 case CSS_VAL_LARGE:
    03715                     style->setMarqueeIncrement(Length(36, Fixed)); // 36px.
    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: // We don't support vertical languages, so AHEAD just maps to UP.
    03766                 style->setMarqueeDirection(MUP);
    03767                 break;
    03768             case CSS_VAL_REVERSE:
    03769             case CSS_VAL_DOWN: // REVERSE just maps to DOWN, since we don't do vertical text.
    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   // For now, lump all families but monospace together.
    03800   if (childFont.genericFamily != FontDef::eMonospace &&
    03801       parentFont.genericFamily != FontDef::eMonospace)
    03802     return;
    03803
    03804   // We know the parent is monospace or the child is monospace, and that font
    03805   // size was unspecified.  We want to alter our font size to use the correct
    03806   // "medium" font for our family.
    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 } // namespace khtml

This file is part of the documentation for khtml Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:33:09 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003