Esempio n. 1
0
void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule)
{
    // Obtain the font-family property and the src property.  Both must be defined.
    const CSSMutableStyleDeclaration* style = fontFaceRule->style();
    RefPtr<CSSValue> fontFamily = style->getPropertyCSSValue(CSSPropertyFontFamily);
    RefPtr<CSSValue> src = style->getPropertyCSSValue(CSSPropertySrc);
    RefPtr<CSSValue> unicodeRange = style->getPropertyCSSValue(CSSPropertyUnicodeRange);
    if (!fontFamily || !src || !fontFamily->isValueList() || !src->isValueList() || (unicodeRange && !unicodeRange->isValueList()))
        return;

    CSSValueList* familyList = static_cast<CSSValueList*>(fontFamily.get());
    if (!familyList->length())
        return;

    CSSValueList* srcList = static_cast<CSSValueList*>(src.get());
    if (!srcList->length())
        return;

    CSSValueList* rangeList = static_cast<CSSValueList*>(unicodeRange.get());

    unsigned traitsMask = 0;

    if (RefPtr<CSSValue> fontStyle = style->getPropertyCSSValue(CSSPropertyFontStyle)) {
        if (fontStyle->isPrimitiveValue()) {
            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
            list->append(fontStyle);
            fontStyle = list;
        } else if (!fontStyle->isValueList())
            return;

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

        for (unsigned i = 0; i < numStyles; ++i) {
            switch (static_cast<CSSPrimitiveValue*>(styleList->itemWithoutBoundsCheck(i))->getIdent()) {
            case CSSValueAll:
                traitsMask |= FontStyleMask;
                break;
            case CSSValueNormal:
                traitsMask |= FontStyleNormalMask;
                break;
            case CSSValueItalic:
            case CSSValueOblique:
                traitsMask |= FontStyleItalicMask;
                break;
            default:
                break;
            }
        }
    } else
        traitsMask |= FontStyleMask;

    if (RefPtr<CSSValue> fontWeight = style->getPropertyCSSValue(CSSPropertyFontWeight)) {
        if (fontWeight->isPrimitiveValue()) {
            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
            list->append(fontWeight);
            fontWeight = list;
        } else if (!fontWeight->isValueList())
            return;

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

        for (unsigned i = 0; i < numWeights; ++i) {
            switch (static_cast<CSSPrimitiveValue*>(weightList->itemWithoutBoundsCheck(i))->getIdent()) {
            case CSSValueAll:
                traitsMask |= FontWeightMask;
                break;
            case CSSValueBolder:
            case CSSValueBold:
            case CSSValue700:
                traitsMask |= FontWeight700Mask;
                break;
            case CSSValueNormal:
            case CSSValue400:
                traitsMask |= FontWeight400Mask;
                break;
            case CSSValue900:
                traitsMask |= FontWeight900Mask;
                break;
            case CSSValue800:
                traitsMask |= FontWeight800Mask;
                break;
            case CSSValue600:
                traitsMask |= FontWeight600Mask;
                break;
            case CSSValue500:
                traitsMask |= FontWeight500Mask;
                break;
            case CSSValue300:
                traitsMask |= FontWeight300Mask;
                break;
            case CSSValueLighter:
            case CSSValue200:
                traitsMask |= FontWeight200Mask;
                break;
            case CSSValue100:
                traitsMask |= FontWeight100Mask;
                break;
            default:
                break;
            }
        }
    } else
        traitsMask |= FontWeightMask;

    if (RefPtr<CSSValue> fontVariant = style->getPropertyCSSValue(CSSPropertyFontVariant)) {
        if (fontVariant->isPrimitiveValue()) {
            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
            list->append(fontVariant);
            fontVariant = list;
        } else if (!fontVariant->isValueList())
            return;

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

        for (unsigned i = 0; i < numVariants; ++i) {
            switch (static_cast<CSSPrimitiveValue*>(variantList->itemWithoutBoundsCheck(i))->getIdent()) {
            case CSSValueAll:
                traitsMask |= FontVariantMask;
                break;
            case CSSValueNormal:
                traitsMask |= FontVariantNormalMask;
                break;
            case CSSValueSmallCaps:
                traitsMask |= FontVariantSmallCapsMask;
                break;
            default:
                break;
            }
        }
    } else
        traitsMask |= FontVariantMask;

    // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace.
    RefPtr<CSSFontFace> fontFace;

    int srcLength = srcList->length();

    bool foundSVGFont = false;

    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).
        CSSFontFaceSrcValue* item = static_cast<CSSFontFaceSrcValue*>(srcList->itemWithoutBoundsCheck(i));
        CSSFontFaceSource* source = 0;

#if ENABLE(SVG_FONTS)
        foundSVGFont = item->isSVGFontFaceSrc() || item->svgFontFaceElement();
#endif
        if (!item->isLocal()) {
            Settings* settings = m_document ? m_document->frame() ? m_document->frame()->settings() : 0 : 0;
            bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled());
            if (allowDownloading && item->isSupportedFormat() && m_document) {
                CachedFont* cachedFont = m_document->cachedResourceLoader()->requestFont(item->resource());
                if (cachedFont) {
                    source = new CSSFontFaceSource(item->resource(), cachedFont);
#if ENABLE(SVG_FONTS)
                    if (foundSVGFont)
                        source->setHasExternalSVGFont(true);
#endif
                }
            }
        } else {
            source = new CSSFontFaceSource(item->resource());
        }

        if (!fontFace)
            fontFace = CSSFontFace::create(static_cast<FontTraitsMask>(traitsMask));

        if (source) {
#if ENABLE(SVG_FONTS)
            source->setSVGFontFaceElement(item->svgFontFaceElement());
#endif
            fontFace->addSource(source);
        }
    }

    ASSERT(fontFace);

    if (fontFace && !fontFace->isValid())
        return;

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

    // Hash under every single family name.
    int familyLength = familyList->length();
    for (int i = 0; i < familyLength; i++) {
        CSSPrimitiveValue* item = static_cast<CSSPrimitiveValue*>(familyList->itemWithoutBoundsCheck(i));
        String familyName;
        if (item->primitiveType() == CSSPrimitiveValue::CSS_STRING)
            familyName = static_cast<FontFamilyValue*>(item)->familyName();
        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.
            String familyName;
            switch (item->getIdent()) {
            case CSSValueSerif:
                familyName = "-webkit-serif";
                break;
            case CSSValueSansSerif:
                familyName = "-webkit-sans-serif";
                break;
            case CSSValueCursive:
                familyName = "-webkit-cursive";
                break;
            case CSSValueFantasy:
                familyName = "-webkit-fantasy";
                break;
            case CSSValueMonospace:
                familyName = "-webkit-monospace";
                break;
            default:
                break;
            }
        }

        if (familyName.isEmpty())
            continue;

        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]), true);
                    locallyInstalledFontFace->addSource(new CSSFontFaceSource(familyName));
                    ASSERT(locallyInstalledFontFace->isValid());
                    familyLocallyInstalledFaces->append(locallyInstalledFontFace);
                }
            }
        }

        familyFontFaces->append(fontFace);
    }
}
Esempio n. 2
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;
    }
}