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