Beispiel #1
0
String CSSFontFaceSet::familyNameFromPrimitive(const CSSPrimitiveValue& value)
{
    if (value.isFontFamily())
        return value.fontFamily().familyName;
    if (!value.isValueID())
        return { };

    // 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 (value.getValueID()) {
    case CSSValueSerif:
        return serifFamily;
    case CSSValueSansSerif:
        return sansSerifFamily;
    case CSSValueCursive:
        return cursiveFamily;
    case CSSValueFantasy:
        return fantasyFamily;
    case CSSValueMonospace:
        return monospaceFamily;
    case CSSValueWebkitPictograph:
        return pictographFamily;
    default:
        return { };
    }
}
void StyleBuilderFunctions::applyValueCSSPropertyTransformOrigin(StyleResolverState& state, CSSValue* value)
{
    CSSValueList* list = toCSSValueList(value);
    ASSERT(list->length() == 3);
    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0));
    if (primitiveValue->isValueID()) {
        switch (primitiveValue->getValueID()) {
        case CSSValueLeft:
            state.style()->setTransformOriginX(Length(0, Percent));
            break;
        case CSSValueRight:
            state.style()->setTransformOriginX(Length(100, Percent));
            break;
        case CSSValueCenter:
            state.style()->setTransformOriginX(Length(50, Percent));
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    } else {
        state.style()->setTransformOriginX(StyleBuilderConverter::convertLength(state, primitiveValue));
    }

    primitiveValue = toCSSPrimitiveValue(list->item(1));
    if (primitiveValue->isValueID()) {
        switch (primitiveValue->getValueID()) {
        case CSSValueTop:
            state.style()->setTransformOriginY(Length(0, Percent));
            break;
        case CSSValueBottom:
            state.style()->setTransformOriginY(Length(100, Percent));
            break;
        case CSSValueCenter:
            state.style()->setTransformOriginY(Length(50, Percent));
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    } else {
        state.style()->setTransformOriginY(StyleBuilderConverter::convertLength(state, primitiveValue));
    }

    primitiveValue = toCSSPrimitiveValue(list->item(2));
    state.style()->setTransformOriginZ(StyleBuilderConverter::convertComputedLength<float>(state, primitiveValue));
}
void StyleBuilderFunctions::applyValueCSSPropertyTextAlign(StyleResolverState& state, CSSValue* value)
{
    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    if (primitiveValue->isValueID() && primitiveValue->getValueID() != CSSValueWebkitMatchParent)
        state.style()->setTextAlign(*primitiveValue);
    else if (state.parentStyle()->textAlign() == TASTART)
        state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? LEFT : RIGHT);
    else if (state.parentStyle()->textAlign() == TAEND)
        state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? RIGHT : LEFT);
    else
        state.style()->setTextAlign(state.parentStyle()->textAlign());
}
Beispiel #4
0
static bool positionFromThreeOrFourValues(CSSPrimitiveValue** values, CSSValue*& resultX, CSSValue*& resultY)
{
    CSSPrimitiveValue* center = nullptr;
    for (int i = 0; values[i]; i++) {
        CSSPrimitiveValue* currentValue = values[i];
        if (!currentValue->isValueID())
            return false;
        CSSValueID id = currentValue->getValueID();

        if (id == CSSValueCenter) {
            if (center)
                return false;
            center = currentValue;
            continue;
        }

        CSSValue* result = nullptr;
        if (values[i + 1] && !values[i + 1]->isValueID()) {
            result = CSSValuePair::create(currentValue, values[++i], CSSValuePair::KeepIdenticalValues);
        } else {
            result = currentValue;
        }

        if (id == CSSValueLeft || id == CSSValueRight) {
            if (resultX)
                return false;
            resultX = result;
        } else {
            ASSERT(id == CSSValueTop || id == CSSValueBottom);
            if (resultY)
                return false;
            resultY = result;
        }
    }

    if (center) {
        ASSERT(resultX || resultY);
        if (resultX && resultY)
            return false;
        if (!resultX)
            resultX = center;
        else
            resultY = center;
    }

    ASSERT(resultX && resultY);
    return true;
}
void StyleBuilderFunctions::applyValueCSSPropertyTextAlign(StyleResolverState& state, CSSValue* value)
{
    if (!value->isPrimitiveValue())
        return;

    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    // FIXME : Per http://www.w3.org/TR/css3-text/#text-align0 can now take <string> but this is not implemented in the
    // rendering code.
    if (primitiveValue->isString())
        return;

    if (primitiveValue->isValueID() && primitiveValue->getValueID() != CSSValueWebkitMatchParent)
        state.style()->setTextAlign(*primitiveValue);
    else if (state.parentStyle()->textAlign() == TASTART)
        state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? LEFT : RIGHT);
    else if (state.parentStyle()->textAlign() == TAEND)
        state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? RIGHT : LEFT);
    else
        state.style()->setTextAlign(state.parentStyle()->textAlign());
}
Beispiel #6
0
bool FontFace::setFamilyValue(CSSValueList* familyList)
{
    // The font-family descriptor has to have exactly one family name.
    if (familyList->length() != 1)
        return false;

    CSSPrimitiveValue* familyValue = toCSSPrimitiveValue(familyList->itemWithoutBoundsCheck(0));
    AtomicString family;
    if (familyValue->isString()) {
        family = AtomicString(familyValue->getStringValue());
    } else if (familyValue->isValueID()) {
        // 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 (familyValue->getValueID()) {
        case CSSValueSerif:
            family =  FontFamilyNames::webkit_serif;
            break;
        case CSSValueSansSerif:
            family =  FontFamilyNames::webkit_sans_serif;
            break;
        case CSSValueCursive:
            family =  FontFamilyNames::webkit_cursive;
            break;
        case CSSValueFantasy:
            family =  FontFamilyNames::webkit_fantasy;
            break;
        case CSSValueMonospace:
            family =  FontFamilyNames::webkit_monospace;
            break;
        case CSSValueWebkitPictograph:
            family =  FontFamilyNames::webkit_pictograph;
            break;
        default:
            return false;
        }
    }
    m_family = family;
    return true;
}
void StyleBuilderFunctions::applyValueCSSPropertyBaselineShift(StyleResolverState& state, CSSValue* value)
{
    SVGComputedStyle& svgStyle = state.style()->accessSVGStyle();
    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    if (!primitiveValue->isValueID()) {
        svgStyle.setBaselineShift(BS_LENGTH);
        svgStyle.setBaselineShiftValue(StyleBuilderConverter::convertLength(state, primitiveValue));
        return;
    }
    switch (primitiveValue->getValueID()) {
    case CSSValueBaseline:
        svgStyle.setBaselineShift(BS_LENGTH);
        svgStyle.setBaselineShiftValue(Length(Fixed));
        return;
    case CSSValueSub:
        svgStyle.setBaselineShift(BS_SUB);
        return;
    case CSSValueSuper:
        svgStyle.setBaselineShift(BS_SUPER);
        return;
    default:
        ASSERT_NOT_REACHED();
    }
}
Beispiel #8
0
static bool isVerticalPositionKeywordOnly(const CSSPrimitiveValue& value)
{
    return value.isValueID() && (value.getValueID() == CSSValueTop || value.getValueID() == CSSValueBottom);
}
Beispiel #9
0
static bool isHorizontalPositionKeywordOnly(const CSSPrimitiveValue& value)
{
    return value.isValueID() && (value.getValueID() == CSSValueLeft || value.getValueID() == CSSValueRight);
}
Beispiel #10
0
void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule)
{
    // Obtain the font-family property and the src property.  Both must be defined.
    const StylePropertySet& style = fontFaceRule->properties();
    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 = toCSSValueList(fontFamily.get());
    if (!familyList->length())
        return;

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

    CSSValueList* rangeList = toCSSValueList(unicodeRange.get());

    unsigned traitsMask = 0;

    if (RefPtr<CSSValue> fontStyle = style.getPropertyCSSValue(CSSPropertyFontStyle)) {
        if (!fontStyle->isPrimitiveValue())
            return;

        switch (toCSSPrimitiveValue(fontStyle.get())->getValueID()) {
        case CSSValueNormal:
            traitsMask |= FontStyleNormalMask;
            break;
        case CSSValueItalic:
        case CSSValueOblique:
            traitsMask |= FontStyleItalicMask;
            break;
        default:
            break;
        }
    } else
        traitsMask |= FontStyleNormalMask;

    if (RefPtr<CSSValue> fontWeight = style.getPropertyCSSValue(CSSPropertyFontWeight)) {
        if (!fontWeight->isPrimitiveValue())
            return;

        switch (toCSSPrimitiveValue(fontWeight.get())->getValueID()) {
        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 CSSValue200:
            traitsMask |= FontWeight200Mask;
            break;
        case CSSValue100:
            traitsMask |= FontWeight100Mask;
            break;
        default:
            break;
        }
    } else
        traitsMask |= FontWeight400Mask;

    if (RefPtr<CSSValue> fontVariant = style.getPropertyCSSValue(CSSPropertyFontVariant)) {
        // font-variant descriptor can be a value list.
        if (fontVariant->isPrimitiveValue()) {
            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
            list->append(fontVariant);
            fontVariant = list;
        } else if (!fontVariant->isValueList())
            return;

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

        for (unsigned i = 0; i < numVariants; ++i) {
            switch (toCSSPrimitiveValue(variantList->itemWithoutBoundsCheck(i))->getValueID()) {
                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 = toCSSFontFaceSrcValue(srcList->itemWithoutBoundsCheck(i));
        OwnPtr<CSSFontFaceSource> source;

#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 = item->cachedFont(m_document);
                if (cachedFont) {
                    source = adoptPtr(new CSSFontFaceSource(item->resource(), cachedFont));
#if ENABLE(SVG_FONTS)
                    if (foundSVGFont)
                        source->setHasExternalSVGFont(true);
#endif
                }
            }
        } else {
            source = adoptPtr(new CSSFontFaceSource(item->resource()));
        }

        if (!fontFace) {
            RefPtr<CSSFontFaceRule> rule;
#if ENABLE(FONT_LOAD_EVENTS)
            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=112116 - This CSSFontFaceRule has no parent.
            if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled())
                rule = static_pointer_cast<CSSFontFaceRule>(fontFaceRule->createCSSOMWrapper());
#endif
            fontFace = CSSFontFace::create(static_cast<FontTraitsMask>(traitsMask), rule);
        }

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

    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 = toCSSPrimitiveValue(familyList->itemWithoutBoundsCheck(i));
        String familyName;
        if (item->isString()) {
            familyName = item->getStringValue();
        } else if (item->isValueID()) {
            // 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->getValueID()) {
                case CSSValueSerif:
                    familyName = serifFamily;
                    break;
                case CSSValueSansSerif:
                    familyName = sansSerifFamily;
                    break;
                case CSSValueCursive:
                    familyName = cursiveFamily;
                    break;
                case CSSValueFantasy:
                    familyName = fantasyFamily;
                    break;
                case CSSValueMonospace:
                    familyName = monospaceFamily;
                    break;
                case CSSValueWebkitPictograph:
                    familyName = pictographFamily;
                    break;
                default:
                    break;
            }
        }

        if (familyName.isEmpty())
            continue;

        OwnPtr<Vector<RefPtr<CSSFontFace> > >& familyFontFaces = m_fontFaces.add(familyName, nullptr).iterator->value;
        if (!familyFontFaces) {
            familyFontFaces = adoptPtr(new Vector<RefPtr<CSSFontFace> >);

            ASSERT(!m_locallyInstalledFontFaces.contains(familyName));

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

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

                m_locallyInstalledFontFaces.set(familyName, familyLocallyInstalledFaces.release());
            }
        }

        familyFontFaces->append(fontFace);
        
        ++m_version;
    }
}