khtml Library API Documentation

css_valueimpl.cpp

00001 
00023 #include "dom/css_value.h"
00024 #include "dom/dom_exception.h"
00025 #include "dom/dom_string.h"
00026 
00027 #include "css/css_valueimpl.h"
00028 #include "css/css_ruleimpl.h"
00029 #include "css/css_stylesheetimpl.h"
00030 #include "css/cssparser.h"
00031 #include "css/cssproperties.h"
00032 #include "css/cssvalues.h"
00033 
00034 #include "xml/dom_stringimpl.h"
00035 #include "xml/dom_docimpl.h"
00036 
00037 #include "misc/loader.h"
00038 
00039 #include "rendering/font.h"
00040 #include "rendering/render_style.h"
00041 
00042 #include <kdebug.h>
00043 #include <qregexp.h>
00044 #include <qpaintdevice.h>
00045 #include <qpaintdevicemetrics.h>
00046 
00047 // Hack for debugging purposes
00048 extern DOM::DOMString getPropertyName(unsigned short id);
00049 
00050 using khtml::FontDef;
00051 
00052 using namespace DOM;
00053 
00054 CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent)
00055     : StyleBaseImpl(parent)
00056 {
00057     m_lstValues = 0;
00058     m_node = 0;
00059 }
00060 
00061 CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent, QPtrList<CSSProperty> *lstValues)
00062     : StyleBaseImpl(parent)
00063 {
00064     m_lstValues = lstValues;
00065     m_node = 0;
00066 }
00067 
00068 CSSStyleDeclarationImpl&  CSSStyleDeclarationImpl::operator= (const CSSStyleDeclarationImpl& o)
00069 {
00070     // don't attach it to the same node, just leave the current m_node value
00071     delete m_lstValues;
00072     m_lstValues = 0;
00073     if (o.m_lstValues) {
00074         m_lstValues = new QPtrList<CSSProperty>;
00075         m_lstValues->setAutoDelete( true );
00076 
00077         QPtrListIterator<CSSProperty> lstValuesIt(*o.m_lstValues);
00078         for (lstValuesIt.toFirst(); lstValuesIt.current(); ++lstValuesIt)
00079             m_lstValues->append(new CSSProperty(*lstValuesIt.current()));
00080     }
00081 
00082     return *this;
00083 }
00084 
00085 CSSStyleDeclarationImpl::~CSSStyleDeclarationImpl()
00086 {
00087     delete m_lstValues;
00088     // we don't use refcounting for m_node, to avoid cyclic references (see ElementImpl)
00089 }
00090 
00091 DOMString CSSStyleDeclarationImpl::getPropertyValue( int propertyID ) const
00092 {
00093     if(!m_lstValues) return DOMString();
00094     CSSValueImpl* value = getPropertyCSSValue( propertyID );
00095     if ( value )
00096         return value->cssText();
00097 
00098     // Shorthand and 4-values properties
00099     switch ( propertyID ) {
00100     case CSS_PROP_BACKGROUND_POSITION:
00101     {
00102         // ## Is this correct? The code in cssparser.cpp is confusing
00103         const int properties[2] = { CSS_PROP_BACKGROUND_POSITION_X,
00104                                     CSS_PROP_BACKGROUND_POSITION_Y };
00105         return getShortHandValue( properties, 2 );
00106     }
00107     case CSS_PROP_BACKGROUND:
00108     {
00109         const int properties[5] = { CSS_PROP_BACKGROUND_IMAGE, CSS_PROP_BACKGROUND_REPEAT,
00110                                     CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION,
00111                                     CSS_PROP_BACKGROUND_COLOR };
00112         return getShortHandValue( properties, 5 );
00113     }
00114     case CSS_PROP_BORDER:
00115     {
00116         const int properties[3] = { CSS_PROP_BORDER_WIDTH, CSS_PROP_BORDER_STYLE,
00117                                     CSS_PROP_BORDER_COLOR };
00118         return getShortHandValue( properties, 3 );
00119     }
00120     case CSS_PROP_BORDER_TOP:
00121     {
00122         const int properties[3] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_TOP_STYLE,
00123                                     CSS_PROP_BORDER_TOP_COLOR};
00124         return getShortHandValue( properties, 3 );
00125     }
00126     case CSS_PROP_BORDER_RIGHT:
00127     {
00128         const int properties[3] = { CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_RIGHT_STYLE,
00129                                     CSS_PROP_BORDER_RIGHT_COLOR};
00130         return getShortHandValue( properties, 3 );
00131     }
00132     case CSS_PROP_BORDER_BOTTOM:
00133     {
00134         const int properties[3] = { CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_BOTTOM_STYLE,
00135                                     CSS_PROP_BORDER_BOTTOM_COLOR};
00136         return getShortHandValue( properties, 3 );
00137     }
00138     case CSS_PROP_BORDER_LEFT:
00139     {
00140         const int properties[3] = { CSS_PROP_BORDER_LEFT_WIDTH, CSS_PROP_BORDER_LEFT_STYLE,
00141                                     CSS_PROP_BORDER_LEFT_COLOR};
00142         return getShortHandValue( properties, 3 );
00143     }
00144     case CSS_PROP_OUTLINE:
00145     {
00146         const int properties[3] = { CSS_PROP_OUTLINE_WIDTH, CSS_PROP_OUTLINE_STYLE,
00147                                     CSS_PROP_OUTLINE_COLOR };
00148         return getShortHandValue( properties, 3 );
00149     }
00150     case CSS_PROP_BORDER_COLOR:
00151     {
00152         const int properties[4] = { CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_RIGHT_COLOR,
00153                                     CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_LEFT_COLOR };
00154         return get4Values( properties );
00155     }
00156     case CSS_PROP_BORDER_WIDTH:
00157     {
00158         const int properties[4] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_RIGHT_WIDTH,
00159                                     CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_LEFT_WIDTH };
00160         return get4Values( properties );
00161     }
00162     case CSS_PROP_BORDER_STYLE:
00163     {
00164         const int properties[4] = { CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_RIGHT_STYLE,
00165                                     CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_LEFT_STYLE };
00166         return get4Values( properties );
00167     }
00168     case CSS_PROP_MARGIN:
00169     {
00170         const int properties[4] = { CSS_PROP_MARGIN_TOP, CSS_PROP_MARGIN_RIGHT,
00171                                     CSS_PROP_MARGIN_BOTTOM, CSS_PROP_MARGIN_LEFT };
00172         return get4Values( properties );
00173     }
00174     case CSS_PROP_PADDING:
00175     {
00176         const int properties[4] = { CSS_PROP_PADDING_TOP, CSS_PROP_PADDING_RIGHT,
00177                                     CSS_PROP_PADDING_BOTTOM, CSS_PROP_PADDING_LEFT };
00178         return get4Values( properties );
00179     }
00180     case CSS_PROP_LIST_STYLE:
00181     {
00182         const int properties[3] = { CSS_PROP_LIST_STYLE_TYPE, CSS_PROP_LIST_STYLE_POSITION,
00183                                     CSS_PROP_LIST_STYLE_IMAGE };
00184         return getShortHandValue( properties, 3 );
00185     }
00186     }
00187     //kdDebug() << k_funcinfo << "property not found:" << propertyID << endl;
00188     return DOMString();
00189 }
00190 
00191 DOMString CSSStyleDeclarationImpl::get4Values( const int* properties ) const
00192 {
00193     DOMString res;
00194     for ( int i = 0 ; i < 4 ; ++i ) {
00195         CSSValueImpl* value = getPropertyCSSValue( properties[i] );
00196         if ( !value ) { // apparently all 4 properties must be specified.
00197             return DOMString();
00198         }
00199         if ( i > 0 )
00200             res += " ";
00201         res += value->cssText();
00202     }
00203     return res;
00204 }
00205 
00206 DOMString CSSStyleDeclarationImpl::getShortHandValue( const int* properties, int number ) const
00207 {
00208     DOMString res;
00209     for ( int i = 0 ; i < number ; ++i ) {
00210         CSSValueImpl* value = getPropertyCSSValue( properties[i] );
00211         if ( value ) { // TODO provide default value if !value
00212             if ( !res.isNull() )
00213                 res += " ";
00214             res += value->cssText();
00215         }
00216     }
00217     return res;
00218 }
00219 
00220  CSSValueImpl *CSSStyleDeclarationImpl::getPropertyCSSValue( int propertyID ) const
00221 {
00222     if(!m_lstValues) return 0;
00223 
00224     QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
00225     CSSProperty *current;
00226     for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt )
00227         if (current->m_id == propertyID && !current->nonCSSHint)
00228             return current->value();
00229     return 0;
00230 }
00231 
00232 DOMString CSSStyleDeclarationImpl::removeProperty( int propertyID, bool NonCSSHint )
00233 {
00234     if(!m_lstValues) return DOMString();
00235     DOMString value;
00236 
00237     QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
00238      CSSProperty *current;
00239      for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt )  {
00240          if (current->m_id == propertyID && NonCSSHint == current->nonCSSHint) {
00241              value = current->value()->cssText();
00242              m_lstValues->removeRef(current);
00243              setChanged();
00244          break;
00245         }
00246      }
00247 
00248     return value;
00249 }
00250 
00251 void CSSStyleDeclarationImpl::setChanged()
00252 {
00253     if (m_node) {
00254         m_node->setChanged();
00255         return;
00256     }
00257 
00258     // ### quick&dirty hack for KDE 3.0... make this MUCH better! (Dirk)
00259     for (StyleBaseImpl* stylesheet = this; stylesheet; stylesheet = stylesheet->parent())
00260         if (stylesheet->isCSSStyleSheet()) {
00261             static_cast<CSSStyleSheetImpl*>(stylesheet)->doc()->updateStyleSelector();
00262             break;
00263         }
00264 }
00265 
00266 void CSSStyleDeclarationImpl::removeCSSHints()
00267 {
00268     if (!m_lstValues)
00269     return;
00270 
00271     for (int i = (int)m_lstValues->count()-1; i >= 0; i--) {
00272     if (!m_lstValues->at(i)->nonCSSHint)
00273         m_lstValues->remove(i);
00274     }
00275 }
00276 
00277 bool CSSStyleDeclarationImpl::getPropertyPriority( int propertyID ) const
00278 {
00279     if ( m_lstValues) {
00280     QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
00281     CSSProperty *current;
00282     for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) {
00283         if( propertyID == current->m_id )
00284         return current->m_bImportant;
00285     }
00286     }
00287     return false;
00288 }
00289 
00290 bool CSSStyleDeclarationImpl::setProperty(int id, const DOMString &value, bool important, bool nonCSSHint)
00291 {
00292     if(!m_lstValues) {
00293     m_lstValues = new QPtrList<CSSProperty>;
00294     m_lstValues->setAutoDelete(true);
00295     }
00296 
00297     CSSParser parser( strictParsing );
00298     bool success = parser.parseValue( this, id, value, important, nonCSSHint );
00299     if(!success)
00300     kdDebug( 6080 ) << "CSSStyleDeclarationImpl::setProperty invalid property: [" << getPropertyName(id).string()
00301             << "] value: [" << value.string() << "]"<< endl;
00302     else
00303         setChanged();
00304     return success;
00305 }
00306 
00307 void CSSStyleDeclarationImpl::setProperty(int id, int value, bool important, bool nonCSSHint)
00308 {
00309     if(!m_lstValues) {
00310     m_lstValues = new QPtrList<CSSProperty>;
00311     m_lstValues->setAutoDelete(true);
00312     }
00313     removeProperty(id, nonCSSHint );
00314 
00315     CSSValueImpl * cssValue = new CSSPrimitiveValueImpl(value);
00316     setParsedValue(id, cssValue, important, nonCSSHint, m_lstValues);
00317     setChanged();
00318 }
00319 
00320 void CSSStyleDeclarationImpl::setLengthProperty(int id, const DOM::DOMString &value, bool important, bool nonCSSHint, bool _multiLength )
00321 {
00322     bool parseMode = strictParsing;
00323     strictParsing = false;
00324     multiLength = _multiLength;
00325     setProperty( id, value, important, nonCSSHint);
00326     strictParsing = parseMode;
00327     multiLength = false;
00328 }
00329 
00330 void CSSStyleDeclarationImpl::setProperty ( const DOMString &propertyString)
00331 {
00332     if(!m_lstValues) {
00333     m_lstValues = new QPtrList<CSSProperty>;
00334     m_lstValues->setAutoDelete( true );
00335     }
00336 
00337     CSSParser parser( strictParsing );
00338     parser.parseDeclaration( this, propertyString, false );
00339     setChanged();
00340 }
00341 
00342 unsigned long CSSStyleDeclarationImpl::length() const
00343 {
00344     return m_lstValues ? m_lstValues->count() : 0;
00345 }
00346 
00347 DOMString CSSStyleDeclarationImpl::item( unsigned long index ) const
00348 {
00349     if(m_lstValues && index < m_lstValues->count() && m_lstValues->at(index))
00350     return getPropertyName(m_lstValues->at(index)->m_id);
00351     return DOMString();
00352 }
00353 
00354 CSSRuleImpl *CSSStyleDeclarationImpl::parentRule() const
00355 {
00356     return (m_parent && m_parent->isRule() ) ?
00357     static_cast<CSSRuleImpl *>(m_parent) : 0;
00358 }
00359 
00360 DOM::DOMString CSSStyleDeclarationImpl::cssText() const
00361 {
00362     DOMString result;
00363 
00364     if ( m_lstValues) {
00365     QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
00366     CSSProperty *current;
00367     for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) {
00368         result += current->cssText();
00369     }
00370     }
00371 
00372     return result;
00373 }
00374 
00375 void CSSStyleDeclarationImpl::setCssText(DOM::DOMString text)
00376 {
00377     if (m_lstValues) {
00378     m_lstValues->clear();
00379     } else {
00380     m_lstValues = new QPtrList<CSSProperty>;
00381     m_lstValues->setAutoDelete( true );
00382     }
00383 
00384     CSSParser parser( strictParsing );
00385     parser.parseDeclaration( this, text, false );
00386     setChanged();
00387 }
00388 
00389 bool CSSStyleDeclarationImpl::parseString( const DOMString &/*string*/, bool )
00390 {
00391     kdDebug() << "WARNING: CSSStyleDeclarationImpl::parseString, unimplemented, was called" << endl;
00392     return false;
00393     // ###
00394 }
00395 
00396 
00397 // --------------------------------------------------------------------------------------
00398 
00399 unsigned short CSSInheritedValueImpl::cssValueType() const
00400 {
00401     return CSSValue::CSS_INHERIT;
00402 }
00403 
00404 DOM::DOMString CSSInheritedValueImpl::cssText() const
00405 {
00406     return DOMString("inherited");
00407 }
00408 
00409 unsigned short CSSInitialValueImpl::cssValueType() const
00410 {
00411     return CSSValue::CSS_INITIAL;
00412 }
00413 
00414 DOM::DOMString CSSInitialValueImpl::cssText() const
00415 {
00416     return DOMString("initial");
00417 }
00418 
00419 // ----------------------------------------------------------------------------------------
00420 
00421 CSSValueListImpl::~CSSValueListImpl()
00422 {
00423     CSSValueImpl *val = m_values.first();
00424     while( val ) {
00425     val->deref();
00426     val = m_values.next();
00427     }
00428 }
00429 
00430 unsigned short CSSValueListImpl::cssValueType() const
00431 {
00432     return CSSValue::CSS_VALUE_LIST;
00433 }
00434 
00435 void CSSValueListImpl::append(CSSValueImpl *val)
00436 {
00437     m_values.append(val);
00438     val->ref();
00439 }
00440 
00441 DOM::DOMString CSSValueListImpl::cssText() const
00442 {
00443     DOMString result = "";
00444 
00445     for (QPtrListIterator<CSSValueImpl> iterator(m_values); iterator.current(); ++iterator) {
00446     result += iterator.current()->cssText();
00447     }
00448 
00449     return result;
00450 }
00451 
00452 // -------------------------------------------------------------------------------------
00453 
00454 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl()
00455     : CSSValueImpl()
00456 {
00457     m_type = 0;
00458 }
00459 
00460 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(int ident)
00461     : CSSValueImpl()
00462 {
00463     m_value.ident = ident;
00464     m_type = CSSPrimitiveValue::CSS_IDENT;
00465 }
00466 
00467 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(double num, CSSPrimitiveValue::UnitTypes type)
00468 {
00469     m_value.num = num;
00470     m_type = type;
00471 }
00472 
00473 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(const DOMString &str, CSSPrimitiveValue::UnitTypes type)
00474 {
00475     m_value.string = str.implementation();
00476     if(m_value.string) m_value.string->ref();
00477     m_type = type;
00478 }
00479 
00480 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(const Counter &c)
00481 {
00482     m_value.counter = c.handle();
00483     if (m_value.counter)
00484     m_value.counter->ref();
00485     m_type = CSSPrimitiveValue::CSS_COUNTER;
00486 }
00487 
00488 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl( RectImpl *r)
00489 {
00490     m_value.rect = r;
00491     if (m_value.rect)
00492     m_value.rect->ref();
00493     m_type = CSSPrimitiveValue::CSS_RECT;
00494 }
00495 
00496 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(QRgb color)
00497 {
00498     m_value.rgbcolor = color;
00499     m_type = CSSPrimitiveValue::CSS_RGBCOLOR;
00500 }
00501 
00502 CSSPrimitiveValueImpl::~CSSPrimitiveValueImpl()
00503 {
00504     cleanup();
00505 }
00506 
00507 void CSSPrimitiveValueImpl::cleanup()
00508 {
00509     switch(m_type) {
00510     case CSSPrimitiveValue::CSS_STRING:
00511     case CSSPrimitiveValue::CSS_URI:
00512     case CSSPrimitiveValue::CSS_ATTR:
00513     if(m_value.string) m_value.string->deref();
00514         break;
00515     case CSSPrimitiveValue::CSS_COUNTER:
00516     m_value.counter->deref();
00517         break;
00518     case CSSPrimitiveValue::CSS_RECT:
00519     m_value.rect->deref();
00520     default:
00521         break;
00522     }
00523 
00524     m_type = 0;
00525 }
00526 
00527 int CSSPrimitiveValueImpl::computeLength( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics )
00528 {
00529     double result = computeLengthFloat( style, devMetrics );
00530     int intResult = (int)result;
00531 #ifdef APPLE_CHANGES
00532     // This conversion is imprecise, often resulting in values of e.g., 44.99998.  We
00533     // need to go ahead and round if we're really close to the next integer value.
00534     double newResult = (intResult < 0) ? result-0.01 : result+0.01;
00535     int secondIntResult = (int)newResult;
00536     if (secondIntResult != intResult)
00537         return secondIntResult;
00538 #endif
00539     return intResult;
00540 }
00541 
00542 double CSSPrimitiveValueImpl::computeLengthFloat( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics )
00543 {
00544     unsigned short type = primitiveType();
00545 
00546     double dpiY = 72.; // fallback
00547     if ( devMetrics )
00548         dpiY = devMetrics->logicalDpiY();
00549     if ( !khtml::printpainter && dpiY < 96 )
00550         dpiY = 96.;
00551 
00552     double factor = 1.;
00553     switch(type)
00554     {
00555     case CSSPrimitiveValue::CSS_EMS:
00556         factor = style->font().pixelSize();
00557         break;
00558     case CSSPrimitiveValue::CSS_EXS:
00559     {
00560         QFontMetrics fm = style->fontMetrics();
00561 #ifdef APPLE_CHANGES
00562         factor = fm.xHeight();
00563 #else
00564         QRect b = fm.boundingRect('x');
00565         factor = b.height();
00566 #endif
00567         break;
00568     }
00569     case CSSPrimitiveValue::CSS_PX:
00570         break;
00571     case CSSPrimitiveValue::CSS_CM:
00572     factor = dpiY/2.54; //72dpi/(2.54 cm/in)
00573         break;
00574     case CSSPrimitiveValue::CSS_MM:
00575     factor = dpiY/25.4;
00576         break;
00577     case CSSPrimitiveValue::CSS_IN:
00578             factor = dpiY;
00579         break;
00580     case CSSPrimitiveValue::CSS_PT:
00581             factor = dpiY/72.;
00582         break;
00583     case CSSPrimitiveValue::CSS_PC:
00584         // 1 pc == 12 pt
00585             factor = dpiY*12./72.;
00586         break;
00587     default:
00588         return -1;
00589     }
00590 
00591     return floatValue(type)*factor;
00592 }
00593 
00594 void CSSPrimitiveValueImpl::setFloatValue( unsigned short unitType, double floatValue, int &exceptioncode )
00595 {
00596     exceptioncode = 0;
00597     cleanup();
00598     // ### check if property supports this type
00599     if(m_type > CSSPrimitiveValue::CSS_DIMENSION) {
00600     exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
00601     return;
00602     }
00603     //if(m_type > CSSPrimitiveValue::CSS_DIMENSION) throw DOMException(DOMException::INVALID_ACCESS_ERR);
00604     m_value.num = floatValue;
00605     m_type = unitType;
00606 }
00607 
00608 void CSSPrimitiveValueImpl::setStringValue( unsigned short stringType, const DOMString &stringValue, int &exceptioncode )
00609 {
00610     exceptioncode = 0;
00611     cleanup();
00612     //if(m_type < CSSPrimitiveValue::CSS_STRING) throw DOMException(DOMException::INVALID_ACCESS_ERR);
00613     //if(m_type > CSSPrimitiveValue::CSS_ATTR) throw DOMException(DOMException::INVALID_ACCESS_ERR);
00614     if(m_type < CSSPrimitiveValue::CSS_STRING || m_type > CSSPrimitiveValue::CSS_ATTR) {
00615     exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
00616     return;
00617     }
00618     if(stringType != CSSPrimitiveValue::CSS_IDENT)
00619     {
00620     m_value.string = stringValue.implementation();
00621     m_value.string->ref();
00622     m_type = stringType;
00623     }
00624     // ### parse ident
00625 }
00626 
00627 unsigned short CSSPrimitiveValueImpl::cssValueType() const
00628 {
00629     return CSSValue::CSS_PRIMITIVE_VALUE;
00630 }
00631 
00632 bool CSSPrimitiveValueImpl::parseString( const DOMString &/*string*/, bool )
00633 {
00634     // ###
00635     kdDebug() << "WARNING: CSSPrimitiveValueImpl::parseString, unimplemented, was called" << endl;
00636     return false;
00637 }
00638 
00639 int CSSPrimitiveValueImpl::getIdent()
00640 {
00641     if(m_type != CSSPrimitiveValue::CSS_IDENT) return 0;
00642     return m_value.ident;
00643 }
00644 
00645 DOM::DOMString CSSPrimitiveValueImpl::cssText() const
00646 {
00647     // ### return the original value instead of a generated one (e.g. color
00648     // name if it was specified) - check what spec says about this
00649     DOMString text;
00650     switch ( m_type ) {
00651     case CSSPrimitiveValue::CSS_UNKNOWN:
00652         // ###
00653         break;
00654     case CSSPrimitiveValue::CSS_NUMBER:
00655         text = DOMString(QString::number( (int)m_value.num ));
00656         break;
00657     case CSSPrimitiveValue::CSS_PERCENTAGE:
00658         text = DOMString(QString::number( m_value.num ) + "%");
00659         break;
00660     case CSSPrimitiveValue::CSS_EMS:
00661         text = DOMString(QString::number( m_value.num ) + "em");
00662         break;
00663     case CSSPrimitiveValue::CSS_EXS:
00664         text = DOMString(QString::number( m_value.num ) + "ex");
00665         break;
00666     case CSSPrimitiveValue::CSS_PX:
00667         text = DOMString(QString::number( m_value.num ) + "px");
00668         break;
00669     case CSSPrimitiveValue::CSS_CM:
00670         text = DOMString(QString::number( m_value.num ) + "cm");
00671         break;
00672     case CSSPrimitiveValue::CSS_MM:
00673         text = DOMString(QString::number( m_value.num ) + "mm");
00674         break;
00675     case CSSPrimitiveValue::CSS_IN:
00676         text = DOMString(QString::number( m_value.num ) + "in");
00677         break;
00678     case CSSPrimitiveValue::CSS_PT:
00679         text = DOMString(QString::number( m_value.num ) + "pt");
00680         break;
00681     case CSSPrimitiveValue::CSS_PC:
00682         text = DOMString(QString::number( m_value.num ) + "pc");
00683         break;
00684     case CSSPrimitiveValue::CSS_DEG:
00685         text = DOMString(QString::number( m_value.num ) + "deg");
00686         break;
00687     case CSSPrimitiveValue::CSS_RAD:
00688         text = DOMString(QString::number( m_value.num ) + "rad");
00689         break;
00690     case CSSPrimitiveValue::CSS_GRAD:
00691         text = DOMString(QString::number( m_value.num ) + "grad");
00692         break;
00693     case CSSPrimitiveValue::CSS_MS:
00694         text = DOMString(QString::number( m_value.num ) + "ms");
00695         break;
00696     case CSSPrimitiveValue::CSS_S:
00697         text = DOMString(QString::number( m_value.num ) + "s");
00698         break;
00699     case CSSPrimitiveValue::CSS_HZ:
00700         text = DOMString(QString::number( m_value.num ) + "hz");
00701         break;
00702     case CSSPrimitiveValue::CSS_KHZ:
00703         text = DOMString(QString::number( m_value.num ) + "khz");
00704         break;
00705     case CSSPrimitiveValue::CSS_DIMENSION:
00706         // ###
00707         break;
00708     case CSSPrimitiveValue::CSS_STRING:
00709         // ###
00710         break;
00711     case CSSPrimitiveValue::CSS_URI:
00712             text  = "url(";
00713         text += DOMString( m_value.string );
00714             text += ")";
00715         break;
00716     case CSSPrimitiveValue::CSS_IDENT:
00717         text = getValueName(m_value.ident);
00718         break;
00719     case CSSPrimitiveValue::CSS_ATTR:
00720         // ###
00721         break;
00722     case CSSPrimitiveValue::CSS_COUNTER:
00723         // ###
00724         break;
00725     case CSSPrimitiveValue::CSS_RECT:
00726         {
00727             RectImpl* rectVal = getRectValue();
00728             text = "rect(";
00729             text += rectVal->top()->cssText() + " ";
00730             text += rectVal->right()->cssText() + " ";
00731             text += rectVal->bottom()->cssText() + " ";
00732             text += rectVal->left()->cssText() + ")";
00733         }
00734         break;
00735     case CSSPrimitiveValue::CSS_RGBCOLOR:
00736         text = QColor(m_value.rgbcolor).name();
00737         break;
00738     default:
00739         break;
00740     }
00741     return text;
00742 }
00743 
00744 // -----------------------------------------------------------------
00745 
00746 RectImpl::RectImpl()
00747 {
00748     m_top = 0;
00749     m_right = 0;
00750     m_bottom = 0;
00751     m_left = 0;
00752 }
00753 
00754 RectImpl::~RectImpl()
00755 {
00756     if (m_top) m_top->deref();
00757     if (m_right) m_right->deref();
00758     if (m_bottom) m_bottom->deref();
00759     if (m_left) m_left->deref();
00760 }
00761 
00762 void RectImpl::setTop( CSSPrimitiveValueImpl *top )
00763 {
00764     if( top ) top->ref();
00765     if ( m_top ) m_top->deref();
00766     m_top = top;
00767 }
00768 
00769 void RectImpl::setRight( CSSPrimitiveValueImpl *right )
00770 {
00771     if( right ) right->ref();
00772     if ( m_right ) m_right->deref();
00773     m_right = right;
00774 }
00775 
00776 void RectImpl::setBottom( CSSPrimitiveValueImpl *bottom )
00777 {
00778     if( bottom ) bottom->ref();
00779     if ( m_bottom ) m_bottom->deref();
00780     m_bottom = bottom;
00781 }
00782 
00783 void RectImpl::setLeft( CSSPrimitiveValueImpl *left )
00784 {
00785     if( left ) left->ref();
00786     if ( m_left ) m_left->deref();
00787     m_left = left;
00788 }
00789 
00790 // -----------------------------------------------------------------
00791 
00792 CSSImageValueImpl::CSSImageValueImpl(const DOMString &url, const StyleBaseImpl* style)
00793     : CSSPrimitiveValueImpl(url, CSSPrimitiveValue::CSS_URI)
00794 {
00795     khtml::DocLoader *docLoader = 0;
00796     const StyleBaseImpl *root = style;
00797     while (root->parent())
00798     root = root->parent();
00799     if (root->isCSSStyleSheet())
00800     docLoader = static_cast<const CSSStyleSheetImpl*>(root)->docLoader();
00801 
00802     m_image = docLoader->requestImage(url);
00803     if(m_image) m_image->ref(this);
00804 }
00805 
00806 CSSImageValueImpl::CSSImageValueImpl()
00807     : CSSPrimitiveValueImpl(CSS_VAL_NONE)
00808 {
00809     m_image = 0;
00810 }
00811 
00812 CSSImageValueImpl::~CSSImageValueImpl()
00813 {
00814     if(m_image) m_image->deref(this);
00815 }
00816 
00817 // ------------------------------------------------------------------------
00818 
00819 FontFamilyValueImpl::FontFamilyValueImpl( const QString &string)
00820 : CSSPrimitiveValueImpl( DOMString(string), CSSPrimitiveValue::CSS_STRING)
00821 {
00822     static const QRegExp parenReg(" \\(.*\\)$");
00823     static const QRegExp braceReg(" \\[.*\\]$");
00824 
00825     parsedFontName = string;
00826     // a language tag is often added in braces at the end. Remove it.
00827     parsedFontName.replace(parenReg, QString::null);
00828     // remove [Xft] qualifiers
00829     parsedFontName.replace(braceReg, QString::null);
00830 
00831 #ifndef APPLE_CHANGES
00832     const QString &available = KHTMLSettings::availableFamilies();
00833 
00834     parsedFontName = parsedFontName.lower();
00835     // kdDebug(0) << "searching for face '" << parsedFontName << "'" << endl;
00836 
00837     int pos = available.find( ',' + parsedFontName + ',', 0, false );
00838     if ( pos == -1 ) {
00839         // many pages add extra MSs to make sure it's windows only ;(
00840         if ( parsedFontName.startsWith( "ms " ) )
00841             parsedFontName = parsedFontName.mid( 3 );
00842         if ( parsedFontName.endsWith( " ms" ) )
00843             parsedFontName.truncate( parsedFontName.length() - 3 );
00844         pos = available.find( ",ms " + parsedFontName + ',', 0, false );
00845         if ( pos == -1 )
00846             pos = available.find( ',' + parsedFontName + " ms,", 0, false );
00847     }
00848 
00849     if ( pos != -1 ) {
00850        ++pos;
00851        int p = available.find(',', pos);
00852        assert( p != -1 ); // available is supposed to start and end with ,
00853        parsedFontName = available.mid( pos, p - pos);
00854        // kdDebug(0) << "going for '" << parsedFontName << "'" << endl;
00855     } else
00856         parsedFontName = QString::null;
00857 
00858 #endif // !APPLE_CHANGES
00859 }
00860 
00861 FontValueImpl::FontValueImpl()
00862     : style(0), variant(0), weight(0), size(0), lineHeight(0), family(0)
00863 {
00864 }
00865 
00866 FontValueImpl::~FontValueImpl()
00867 {
00868     delete style;
00869     delete variant;
00870     delete weight;
00871     delete size;
00872     delete lineHeight;
00873     delete family;
00874 }
00875 
00876 DOMString FontValueImpl::cssText() const
00877 {
00878     // font variant weight size / line-height family
00879 
00880     DOMString result("");
00881 
00882     if (style) {
00883     result += style->cssText();
00884     }
00885     if (variant) {
00886     if (result.length() > 0) {
00887         result += " ";
00888     }
00889     result += variant->cssText();
00890     }
00891     if (weight) {
00892     if (result.length() > 0) {
00893         result += " ";
00894     }
00895     result += weight->cssText();
00896     }
00897     if (size) {
00898     if (result.length() > 0) {
00899         result += " ";
00900     }
00901     result += size->cssText();
00902     }
00903     if (lineHeight) {
00904     if (!size) {
00905         result += " ";
00906     }
00907     result += "/";
00908     result += lineHeight->cssText();
00909     }
00910     if (family) {
00911     if (result.length() > 0) {
00912         result += " ";
00913     }
00914     result += family->cssText();
00915     }
00916 
00917     return result;
00918 }
00919 
00920 DOMString CSSProperty::cssText() const
00921 {
00922     return getPropertyName(m_id) + DOMString(": ") + m_value->cssText() + (m_bImportant ? DOMString(" !important") : DOMString()) + DOMString("; ");
00923 }
KDE Logo
This file is part of the documentation for khtml Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed May 5 07:22:12 2004 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003