コード例 #1
0
ファイル: css_webfont.cpp プロジェクト: KDE/khtml
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;
    }
}