Пример #1
0
static bool compareCounterActList(const CSSValueListImpl *ca, const CSSValueListImpl *cb)
{
    // weeee....
    CSSValueListImpl *a = const_cast< CSSValueListImpl * >(ca);
    CSSValueListImpl *b = const_cast< CSSValueListImpl * >(cb);

    if(!a && !b)
        return true;
    if(!a || !b)
        return false;
    if(a->length() != b->length())
        return false;
    for(uint i = 0; i < a->length(); i++)
    {
        CSSValueImpl *ai = a->item(i);
        CSSValueImpl *bi = b->item(i);
        assert(ai && ai->cssValueType() == CSSValue::CSS_CUSTOM);
        assert(bi && bi->cssValueType() == CSSValue::CSS_CUSTOM);
        CounterActImpl *caa = static_cast< CounterActImpl * >(ai);
        CounterActImpl *cab = static_cast< CounterActImpl * >(bi);
        if(caa->value() != cab->value())
            return false;
        if(caa->counter() != cab->counter())
            return false;
    }
    return true;
}
DOMString CSSStyleDeclarationImpl::getPropertyValue( const DOMString &propertyName )
{
    CSSValueImpl *val = getPropertyCSSValue( propertyName );
    if ( !val )
	return 0;
    return val->cssText();
}
CSSValueListImpl::~CSSValueListImpl()
{
    CSSValueImpl *val = m_values.first();
    while( val ) {
	val->deref();
	val = m_values.next();
    }
}
DOMString CSSComputedStyleDeclarationImpl::getPropertyValue(int propertyID) const
{
    CSSValueImpl* value = getPropertyCSSValue(propertyID);
    if (value) {
        value->ref();
        DOMString result = value->cssText();
        value->deref();
        return result;
    }
    return "";
}
DOMString CSSStyleDeclarationImpl::getShortHandValue( const int* properties, int number ) const
{
    DOMString res;
    for ( int i = 0 ; i < number ; ++i ) {
        CSSValueImpl* value = getPropertyCSSValue( properties[i] );
        if ( value ) { // TODO provide default value if !value
            if ( !res.isNull() )
                res += " ";
            res += value->cssText();
        }
    }
    return res;
}
DOMString CSSStyleDeclarationImpl::get4Values( const int* properties ) const
{
    DOMString res;
    for ( int i = 0 ; i < 4 ; ++i ) {
        CSSValueImpl* value = getPropertyCSSValue( properties[i] );
        if ( !value ) { // apparently all 4 properties must be specified.
            return DOMString();
        }
        if ( i > 0 )
            res += " ";
        res += value->cssText();
    }
    return res;
}
void HTMLTableElementImpl::parseHTMLAttribute(HTMLAttributeImpl *attr)
{
    switch(attr->id())
    {
    case ATTR_WIDTH:
        addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
        break;
    case ATTR_HEIGHT:
        addCSSLength(attr, CSS_PROP_HEIGHT, attr->value());
        break;
    case ATTR_BORDER:
    {
        m_noBorder = true;
        if (attr->isNull()) break;
        if (attr->decl()) {
            CSSValueImpl* val = attr->decl()->getPropertyCSSValue(CSS_PROP_BORDER_LEFT_WIDTH);
            if (val) {
                val->ref();
                if (val->isPrimitiveValue()) {
                    CSSPrimitiveValueImpl* primVal = static_cast<CSSPrimitiveValueImpl*>(val);
                    m_noBorder = !primVal->getFloatValue(CSSPrimitiveValue::CSS_NUMBER);
                }
                val->deref();
            }
        }
        else {
            // ### this needs more work, as the border value is not only
            //     the border of the box, but also between the cells
            int border = 0;
            if (attr->isEmpty())
                border = 1;
            else
                border = attr->value().toInt();
#ifdef DEBUG_DRAW_BORDER
            border=1;
#endif
            m_noBorder = !border;
            DOMString v = QString::number( border );
            addCSSLength(attr, CSS_PROP_BORDER_WIDTH, v );
        }
#if 0
        // wanted by HTML4 specs
        if (m_noBorder)
            frame = Void, rules = None;
        else
            frame = Box, rules = All;
#endif
        break;
    }
    case ATTR_BGCOLOR:
        addHTMLColor(attr, CSS_PROP_BACKGROUND_COLOR, attr->value());
        break;
    case ATTR_BORDERCOLOR:
        m_solid = attr->decl();
        if (!attr->decl() && !attr->isEmpty()) {
            addHTMLColor(attr, CSS_PROP_BORDER_COLOR, attr->value());
            addCSSProperty(attr, CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID);
            addCSSProperty(attr, CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID);
            addCSSProperty(attr, CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
            addCSSProperty(attr, CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
            m_solid = true;
        }
        break;
    case ATTR_BACKGROUND:
    {
        QString url = khtml::parseURL( attr->value() ).string();
        if (!url.isEmpty())
            addCSSImageProperty(attr, CSS_PROP_BACKGROUND_IMAGE, getDocument()->completeURL(url));
        break;
    }
    case ATTR_FRAME:
#if 0
        if ( strcasecmp( attr->value(), "void" ) == 0 )
            frame = Void;
        else if ( strcasecmp( attr->value(), "border" ) == 0 )
            frame = Box;
        else if ( strcasecmp( attr->value(), "box" ) == 0 )
            frame = Box;
        else if ( strcasecmp( attr->value(), "hsides" ) == 0 )
            frame = Hsides;
        else if ( strcasecmp( attr->value(), "vsides" ) == 0 )
            frame = Vsides;
        else if ( strcasecmp( attr->value(), "above" ) == 0 )
            frame = Above;
        else if ( strcasecmp( attr->value(), "below" ) == 0 )
            frame = Below;
        else if ( strcasecmp( attr->value(), "lhs" ) == 0 )
            frame = Lhs;
        else if ( strcasecmp( attr->value(), "rhs" ) == 0 )
            frame = Rhs;
#endif
        break;
    case ATTR_RULES:
#if 0
        if ( strcasecmp( attr->value(), "none" ) == 0 )
            rules = None;
        else if ( strcasecmp( attr->value(), "groups" ) == 0 )
            rules = Groups;
        else if ( strcasecmp( attr->value(), "rows" ) == 0 )
            rules = Rows;
        else if ( strcasecmp( attr->value(), "cols" ) == 0 )
            rules = Cols;
        else if ( strcasecmp( attr->value(), "all" ) == 0 )
            rules = All;
#endif
        break;
   case ATTR_CELLSPACING:
        if (!attr->value().isEmpty())
            addCSSLength(attr, CSS_PROP_BORDER_SPACING, attr->value());
        break;
    case ATTR_CELLPADDING:
        if (!attr->value().isEmpty())
            padding = kMax( 0, attr->value().toInt() );
        else
            padding = 1;
        if (m_render && m_render->isTable()) {
            static_cast<RenderTable *>(m_render)->setCellPadding(padding);
	    if (!m_render->needsLayout())
	        m_render->setNeedsLayout(true);
        }
        break;
    case ATTR_COLS:
    {
        // ###
#if 0
        int c;
        c = attr->val()->toInt();
        addColumns(c-totalCols);
        break;
#endif
    }
    case ATTR_VSPACE:
        addCSSLength(attr, CSS_PROP_MARGIN_TOP, attr->value());
        addCSSLength(attr, CSS_PROP_MARGIN_BOTTOM, attr->value());
        break;
    case ATTR_HSPACE:
        addCSSLength(attr, CSS_PROP_MARGIN_LEFT, attr->value());
        addCSSLength(attr, CSS_PROP_MARGIN_RIGHT, attr->value());
        break;
    case ATTR_ALIGN:
        if (!attr->value().isEmpty())
            addCSSProperty(attr, CSS_PROP_FLOAT, attr->value());
        break;
    case ATTR_VALIGN:
        if (!attr->value().isEmpty())
            addCSSProperty(attr, CSS_PROP_VERTICAL_ALIGN, attr->value());
        break;
    case ATTR_NOSAVE:
	break;
    default:
        HTMLElementImpl::parseHTMLAttribute(attr);
    }
}
Пример #8
0
void CSSFontSelector::addFontFaceRule(const CSSFontFaceRuleImpl *fontFaceRule)
{
    // Obtain the font-family property and the src property.  Both must be defined.
    const CSSStyleDeclarationImpl *style = fontFaceRule->style();
    CSSValueImpl *fontFamily = style->getPropertyCSSValue(CSS_PROP_FONT_FAMILY);
    CSSValueImpl *src = style->getPropertyCSSValue(CSS_PROP_SRC);
    CSSValueImpl *unicodeRange = style->getPropertyCSSValue(CSS_PROP_UNICODE_RANGE);

    if (!fontFamily || !src || !fontFamily->isValueList() || !src->isValueList() || (unicodeRange && !unicodeRange->isValueList())) {
        return;
    }

    CSSValueListImpl *familyList = static_cast<CSSValueListImpl *>(fontFamily);
    if (!familyList->length()) {
        return;
    }

    CSSValueListImpl *srcList = static_cast<CSSValueListImpl *>(src);
    if (!srcList->length()) {
        return;
    }

//    CSSValueListImpl* rangeList = static_cast<CSSValueListImpl*>(unicodeRange);

    unsigned traitsMask = 0;
    /*
        if (CSSValueImpl* fontStyle = style->getPropertyCSSValue(CSS_PROP_FONT_STYLE)) {

            if (fontStyle->isPrimitiveValue()) {
                CSSValueListImpl* list = new CSSValueListImpl(CSSValueListImpl::Comma);
                list->append(fontStyle);
                fontStyle = list;
            } else if (!fontStyle->isValueList())
                return;

            CSSValueListImpl* styleList = static_cast<CSSValueListImpl*>(fontStyle);
            unsigned numStyles = styleList->length();
            if (!numStyles)
                return;

            for (unsigned i = 0; i < numStyles; ++i) {
                switch (static_cast<CSSPrimitiveValueImpl*>(styleList[i])->getIdent()) {
                    case CSS_ALL:
                        traitsMask |= FontStyleMask;
                        break;
                    case CSS_NORMAL:
                        traitsMask |= FontStyleNormalMask;
                        break;
                    case CSS_ITALIC:
                    case CSS_OBLIQUE:
                        traitsMask |= FontStyleItalicMask;
                        break;
                    default:
                        break;
                }
            }
        } else
            traitsMask |= FontStyleMask;

        if (CSSValueImpl* fontWeight = style->getPropertyCSSValue(CSS_PROP_FONT_WEIGHT)) {
            if (fontWeight->isPrimitiveValue()) {
                CSSValueListImpl* list = new CSSValueListImpl(CSSValueListImpl::Comma);
                list->append(fontWeight);
                fontWeight = list;
            } else if (!fontWeight->isValueList())
                return;

            CSSValueListImpl* weightList = static_cast<CSSValueListImpl*>(fontWeight);
            unsigned numWeights = weightList->length();
            if (!numWeights)
                return;

            for (unsigned i = 0; i < numWeights; ++i) {
                switch (static_cast<CSSPrimitiveValueImpl*>(weightList[i])->getIdent()) {
                    case CSS_VAL_ALL:
                        traitsMask |= FontWeightMask;
                        break;
                    case CSS_VAL_BOLDER:
                    case CSS_VAL_BOLD:
                    case CSS_VAL_700:
                        traitsMask |= FontWeight700Mask;
                        break;
                    case CSS_VAL_NORMAL:
                    case CSS_VAL_400:
                        traitsMask |= FontWeight400Mask;
                        break;
                    case CSS_VAL_900:
                        traitsMask |= FontWeight900Mask;
                        break;
                    case CSS_VAL_800:
                        traitsMask |= FontWeight800Mask;
                        break;
                    case CSS_VAL_600:
                        traitsMask |= FontWeight600Mask;
                        break;
                    case CSS_VAL_500:
                        traitsMask |= FontWeight500Mask;
                        break;
                    case CSS_VAL_300:
                        traitsMask |= FontWeight300Mask;
                        break;
                    case CSS_VAL_LIGHTER:
                    case CSS_VAL_200:
                        traitsMask |= FontWeight200Mask;
                        break;
                    case CSS_VAL_100:
                        traitsMask |= FontWeight100Mask;
                        break;
                    default:
                        break;
                }
            }
        } else
            traitsMask |= FontWeightMask;

        if (CSSValueImpl* fontVariant = style->getPropertyCSSValue(CSS_PROP_FONT_VARIANT)) {
            if (fontVariant->isPrimitiveValue()) {
                CSSValueListImpl* list = new CSSValueListImpl(CSSValueListImpl::Comma);
                list->append(fontVariant);
                fontVariant = list;
            } else if (!fontVariant->isValueList())
                return;

            CSSValueListImpl* variantList = static_cast<CSSValueListImpl*>(fontVariant);
            unsigned numVariants = variantList->length();
            if (!numVariants)
                return;

            for (unsigned i = 0; i < numVariants; ++i) {
                switch (static_cast<CSSPrimitiveValueImpl*>(variantList[i])->getIdent()) {
                    case CSS_VAL_ALL:
                        traitsMask |= FontVariantMask;
                        break;
                    case CSS_VAL_NORMAL:
                        traitsMask |= FontVariantNormalMask;
                        break;
                    case CSS_VAL_SMALL_CAPS:
                        traitsMask |= FontVariantSmallCapsMask;
                        break;
                    default:
                        break;
                }
            }
        } else
            traitsMask |= FontVariantNormalMask;
    */

    // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace.
    CSSFontFace *fontFace = 0;

    const int srcLength = srcList->length();

#if 0
    // ENABLE(SVG_FONTS)
    bool foundSVGFont = false;
#endif
    for (int i = 0; i < srcLength; i++) {
        // An item in the list either specifies a string (local font name) or a URL (remote font to download).
        CSSFontFaceSrcValueImpl *item = static_cast<CSSFontFaceSrcValueImpl *>(srcList->item(i));
        CSSFontFaceSource *source = 0;

#if 0
        // ENABLE(SVG_FONTS)
        foundSVGFont = item->isSVGFontFaceSrc() || item->svgFontFaceElement();
#endif

        if (!item->isLocal()) {
            if (item->isSupportedFormat() && m_document) {
                source = new CSSFontFaceSource(item->resource(), true /*distant*/);
#if 0
                // ENABLE(SVG_FONTS)
                if (foundSVGFont) {
                    cachedFont->setSVGFont(true);
                }
#endif
            }
        } else {
            source = new CSSFontFaceSource(item->resource());
        }

        if (source) {
#if 0
            // ENABLE(SVG_FONTS)
            source->setSVGFontFaceElement(item->svgFontFaceElement());
#endif
            if (!fontFace) {
                fontFace = new CSSFontFace(static_cast<FontTraitsMask>(traitsMask), this);
            }
            fontFace->addSource(source);
        }
    }

    if (!fontFace || !fontFace->isValid()) {
        delete fontFace;
        return;
    }

    /*
        if (rangeList) {
            unsigned numRanges = rangeList->length();
            for (unsigned i = 0; i < numRanges; i++) {
                CSSUnicodeRangeValueImpl* range = static_cast<CSSUnicodeRangeValueImpl*>(rangeList->item(i));
                fontFace->addRange(range->from(), range->to());
            }
        }
    */

    // Hash under every single family name.
    int familyLength = familyList->length();
    for (int i = 0; i < familyLength; i++) {
        CSSPrimitiveValueImpl *item = static_cast<CSSPrimitiveValueImpl *>(familyList->item(i));
        DOMString familyName;
        if (item->primitiveType() == CSSPrimitiveValue::CSS_STRING) {
            familyName = DOMString(static_cast<FontFamilyValueImpl *>(item)->fontName());
        } else if (item->primitiveType() == CSSPrimitiveValue::CSS_IDENT) {
            // We need to use the raw text for all the generic family types, since @font-face is a way of actually
            // defining what font to use for those types.
            switch (item->getIdent()) {
            case CSS_VAL_SERIF:
                familyName = "-khtml-serif";
                break;
            case CSS_VAL_SANS_SERIF:
                familyName = "-khtml-sans-serif";
                break;
            case CSS_VAL_CURSIVE:
                familyName = "-khtml-cursive";
                break;
            case CSS_VAL_FANTASY:
                familyName = "-khtml-fantasy";
                break;
            case CSS_VAL_MONOSPACE:
                familyName = "-khtml-monospace";
                break;
            default:
                break;
            }
        }

        if (familyName.isEmpty()) {
            continue;
        }

        fontFace->addFamilyName(familyName);
        m_locallyInstalledFontFaces.insertMulti(familyName.lower(), fontFace);
        fontFace->ref();

#if 0
        // ENABLE(SVG_FONTS)
        // SVG allows several <font> elements with the same font-family, differing only
        // in ie. font-variant. Be sure to pick up the right one - in getFontData below.
        if (foundSVGFont && (traitsMask & FontVariantSmallCapsMask)) {
            familyName += "-webkit-svg-small-caps";
        }
#endif

        /*
                Vector<RefPtr<CSSFontFace> >* familyFontFaces = m_fontFaces.get(familyName);
                if (!familyFontFaces) {
                    familyFontFaces = new Vector<RefPtr<CSSFontFace> >;
                    m_fontFaces.set(familyName, familyFontFaces);

                    ASSERT(!m_locallyInstalledFontFaces.contains(familyName));
                    Vector<RefPtr<CSSFontFace> >* familyLocallyInstalledFaces;

                    Vector<unsigned> locallyInstalledFontsTraitsMasks;
                    fontCache()->getTraitsInFamily(familyName, locallyInstalledFontsTraitsMasks);
                    unsigned numLocallyInstalledFaces = locallyInstalledFontsTraitsMasks.size();
                    if (numLocallyInstalledFaces) {
                        familyLocallyInstalledFaces = new Vector<RefPtr<CSSFontFace> >;
                        m_locallyInstalledFontFaces.set(familyName, familyLocallyInstalledFaces);

                        for (unsigned i = 0; i < numLocallyInstalledFaces; ++i) {
                            RefPtr<CSSFontFace> locallyInstalledFontFace = CSSFontFace::create(static_cast<FontTraitsMask>(locallyInstalledFontsTraitsMasks[i]));
                            locallyInstalledFontFace->addSource(new CSSFontFaceSource(familyName));
                            ASSERT(locallyInstalledFontFace->isValid());
                            familyLocallyInstalledFaces->append(locallyInstalledFontFace);
                        }
                    }
                }

                familyFontFaces->append(fontFace);
        */
    }

    // Should be impossible, but in case empty/invalid family name makes it through...
    if (fontFace->refCount() < 1) {
        delete fontFace;
    }
}
DOMString CSSStyleDeclarationImpl::getPropertyValue( int propertyID ) const
{
    if(!m_lstValues) return DOMString();

    CSSValueImpl* value = getPropertyCSSValue( propertyID );
    if ( value )
        return value->cssText();

    // Shorthand and 4-values properties
    switch ( propertyID ) {
    case CSS_PROP_BACKGROUND_POSITION:
    {
        // ## Is this correct? The code in cssparser.cpp is confusing
        const int properties[2] = { CSS_PROP_BACKGROUND_POSITION_X,
                                    CSS_PROP_BACKGROUND_POSITION_Y };
        return getShortHandValue( properties, 2 );
    }
    case CSS_PROP_BACKGROUND:
    {
        const int properties[5] = { CSS_PROP_BACKGROUND_IMAGE, CSS_PROP_BACKGROUND_REPEAT,
                                    CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION,
                                    CSS_PROP_BACKGROUND_COLOR };
        return getShortHandValue( properties, 5 );
    }
    case CSS_PROP_BORDER:
    {
        const int properties[3] = { CSS_PROP_BORDER_WIDTH, CSS_PROP_BORDER_STYLE,
                                    CSS_PROP_BORDER_COLOR };
        return getShortHandValue( properties, 3 );
    }
    case CSS_PROP_BORDER_TOP:
    {
        const int properties[3] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_TOP_STYLE,
                                    CSS_PROP_BORDER_TOP_COLOR};
        return getShortHandValue( properties, 3 );
    }
    case CSS_PROP_BORDER_RIGHT:
    {
        const int properties[3] = { CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_RIGHT_STYLE,
                                    CSS_PROP_BORDER_RIGHT_COLOR};
        return getShortHandValue( properties, 3 );
    }
    case CSS_PROP_BORDER_BOTTOM:
    {
        const int properties[3] = { CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_BOTTOM_STYLE,
                                    CSS_PROP_BORDER_BOTTOM_COLOR};
        return getShortHandValue( properties, 3 );
    }
    case CSS_PROP_BORDER_LEFT:
    {
        const int properties[3] = { CSS_PROP_BORDER_LEFT_WIDTH, CSS_PROP_BORDER_LEFT_STYLE,
                                    CSS_PROP_BORDER_LEFT_COLOR};
        return getShortHandValue( properties, 3 );
    }
    case CSS_PROP_OUTLINE:
    {
        const int properties[3] = { CSS_PROP_OUTLINE_WIDTH, CSS_PROP_OUTLINE_STYLE,
                                    CSS_PROP_OUTLINE_COLOR };
        return getShortHandValue( properties, 3 );
    }
    case CSS_PROP_BORDER_COLOR:
    {
        const int properties[4] = { CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_RIGHT_COLOR,
                                    CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_LEFT_COLOR };
        return get4Values( properties );
    }
    case CSS_PROP_BORDER_WIDTH:
    {
        const int properties[4] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_RIGHT_WIDTH,
                                    CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_LEFT_WIDTH };
        return get4Values( properties );
    }
    case CSS_PROP_BORDER_STYLE:
    {
        const int properties[4] = { CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_RIGHT_STYLE,
                                    CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_LEFT_STYLE };
        return get4Values( properties );
    }
    case CSS_PROP_MARGIN:
    {
        const int properties[4] = { CSS_PROP_MARGIN_TOP, CSS_PROP_MARGIN_RIGHT,
                                    CSS_PROP_MARGIN_BOTTOM, CSS_PROP_MARGIN_LEFT };
        return get4Values( properties );
    }
    case CSS_PROP_PADDING:
    {
        const int properties[4] = { CSS_PROP_PADDING_TOP, CSS_PROP_PADDING_RIGHT,
                                    CSS_PROP_PADDING_BOTTOM, CSS_PROP_PADDING_LEFT };
        return get4Values( properties );
    }
    case CSS_PROP_LIST_STYLE:
    {
        const int properties[3] = { CSS_PROP_LIST_STYLE_TYPE, CSS_PROP_LIST_STYLE_POSITION,
                                    CSS_PROP_LIST_STYLE_IMAGE };
        return getShortHandValue( properties, 3 );
    }
    }
    //kdDebug() << k_funcinfo << "property not found:" << propertyID << endl;
    return DOMString();
}