Ejemplo n.º 1
0
void CSSToStyleMap::mapNinePieceImage(StyleResolverState& state, CSSPropertyID property, CSSValue* value, NinePieceImage& image)
{
    // If we're not a value list, then we are "none" and don't need to alter the empty image at all.
    if (!value || !value->isValueList())
        return;

    // Retrieve the border image value.
    CSSValueList* borderImage = toCSSValueList(value);

    // Set the image (this kicks off the load).
    CSSPropertyID imageProperty;
    if (property == CSSPropertyWebkitBorderImage)
        imageProperty = CSSPropertyBorderImageSource;
    else if (property == CSSPropertyWebkitMaskBoxImage)
        imageProperty = CSSPropertyWebkitMaskBoxImageSource;
    else
        imageProperty = property;

    for (unsigned i = 0 ; i < borderImage->length() ; ++i) {
        CSSValue* current = borderImage->item(i);

        if (current->isImageValue() || current->isImageGeneratorValue() || current->isImageSetValue())
            image.setImage(state.styleImage(imageProperty, current));
        else if (current->isBorderImageSliceValue())
            mapNinePieceImageSlice(state, current, image);
        else if (current->isValueList()) {
            CSSValueList* slashList = toCSSValueList(current);
            size_t length = slashList->length();
            // Map in the image slices.
            if (length && slashList->item(0)->isBorderImageSliceValue())
                mapNinePieceImageSlice(state, slashList->item(0), image);

            // Map in the border slices.
            if (length > 1)
                image.setBorderSlices(mapNinePieceImageQuad(state, slashList->item(1)));

            // Map in the outset.
            if (length > 2)
                image.setOutset(mapNinePieceImageQuad(state, slashList->item(2)));
        } else if (current->isPrimitiveValue()) {
            // Set the appropriate rules for stretch/round/repeat of the slices.
            mapNinePieceImageRepeat(state, current, image);
        }
    }

    if (property == CSSPropertyWebkitBorderImage) {
        // We have to preserve the legacy behavior of -webkit-border-image and make the border slices
        // also set the border widths. We don't need to worry about percentages, since we don't even support
        // those on real borders yet.
        if (image.borderSlices().top().isLength() && image.borderSlices().top().length().isFixed())
            state.style()->setBorderTopWidth(image.borderSlices().top().length().value());
        if (image.borderSlices().right().isLength() && image.borderSlices().right().length().isFixed())
            state.style()->setBorderRightWidth(image.borderSlices().right().length().value());
        if (image.borderSlices().bottom().isLength() && image.borderSlices().bottom().length().isFixed())
            state.style()->setBorderBottomWidth(image.borderSlices().bottom().length().value());
        if (image.borderSlices().left().isLength() && image.borderSlices().left().length().isFixed())
            state.style()->setBorderLeftWidth(image.borderSlices().left().length().value());
    }
}
Ejemplo n.º 2
0
PassRefPtr<CSSFontFace> FontFace::createCSSFontFace(Document* document)
{
    RefPtr<CSSFontFace> cssFontFace = CSSFontFace::create(this);

    // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace.
    CSSValueList* srcList = toCSSValueList(m_src.get());
    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 = document ? document->frame() ? document->frame()->settings() : 0 : 0;
            bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled());
            if (allowDownloading && item->isSupportedFormat() && document) {
                FontResource* fetched = item->fetch(document);
                if (fetched) {
                    source = adoptPtr(new CSSFontFaceSource(item->resource(), fetched));
#if ENABLE(SVG_FONTS)
                    if (foundSVGFont)
                        source->setHasExternalSVGFont(true);
#endif
                }
            }
        } else {
            source = adoptPtr(new CSSFontFaceSource(item->resource()));
        }

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

    if (CSSValueList* rangeList = toCSSValueList(m_unicodeRange.get())) {
        unsigned numRanges = rangeList->length();
        for (unsigned i = 0; i < numRanges; i++) {
            CSSUnicodeRangeValue* range = toCSSUnicodeRangeValue(rangeList->itemWithoutBoundsCheck(i));
            cssFontFace->ranges().add(range->from(), range->to());
        }
    }
    return cssFontFace;
}
bool ShadowStyleInterpolation::usesDefaultStyleInterpolation(const CSSValue& start, const CSSValue& end)
{
    if (start.isValueList() && end.isValueList() && toCSSValueList(start).length() == toCSSValueList(end).length()) {
        const CSSValueList* startList = toCSSValueList(&start);
        const CSSValueList* endList = toCSSValueList(&end);
        for (size_t i = 0; i < toCSSValueList(start).length(); i++) {
            if (startList->item(i)->isShadowValue() && endList->item(i)->isShadowValue()
                && toCSSShadowValue(startList->item(i))->style != toCSSShadowValue(endList->item(i))->style)
                return true;
        }
    }
    return false;
}
Ejemplo n.º 4
0
PassRefPtr<FilterStyleInterpolation::FilterListStyleInterpolation> FilterStyleInterpolation::maybeCreateList(const CSSValue& start, const CSSValue& end, CSSPropertyID property)
{
    if (start.isCSSWideKeyword() || end.isCSSWideKeyword())
        return nullptr;

    ASSERT(start.isValueList() || toCSSPrimitiveValue(start).getValueID() == CSSValueNone);
    ASSERT(end.isValueList() || toCSSPrimitiveValue(end).getValueID() == CSSValueNone);

    if (!start.isValueList() && !end.isValueList())
        return nullptr;

    return maybeCreateFromList(
        start.isValueList() ? toCSSValueList(start) : *CSSValueList::createSpaceSeparated(),
        end.isValueList() ? toCSSValueList(end) : *CSSValueList::createSpaceSeparated(),
        property);
}
Ejemplo n.º 5
0
PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const
{
    switch (classType()) {
    case PrimitiveClass:
        return toCSSPrimitiveValue(this)->cloneForCSSOM();
    case ValueListClass:
        return toCSSValueList(this)->cloneForCSSOM();
    case ImageClass:
    case CursorImageClass:
        return toCSSImageValue(this)->cloneForCSSOM();
#if ENABLE(CSS_FILTERS)
    case WebKitCSSFilterClass:
        return toWebKitCSSFilterValue(this)->cloneForCSSOM();
#endif
    case WebKitCSSTransformClass:
        return toWebKitCSSTransformValue(this)->cloneForCSSOM();
#if ENABLE(CSS_IMAGE_SET)
    case ImageSetClass:
        return toCSSImageSetValue(this)->cloneForCSSOM();
#endif
#if ENABLE(SVG)
    case SVGColorClass:
        return toSVGColor(this)->cloneForCSSOM();
    case SVGPaintClass:
        return toSVGPaint(this)->cloneForCSSOM();
#endif
    default:
        ASSERT(!isSubtypeExposedToCSSOM());
        return TextCloneCSSValue::create(classType(), cssText());
    }
}
InterpolationValue CSSTransformInterpolationType::maybeConvertValue(
    const CSSValue& value,
    const StyleResolverState& state,
    ConversionCheckers& conversionCheckers) const {
  if (value.isValueList()) {
    CSSLengthArray lengthArray;
    for (const CSSValue* item : toCSSValueList(value)) {
      const CSSFunctionValue& transformFunction = toCSSFunctionValue(*item);
      if (transformFunction.functionType() == CSSValueMatrix ||
          transformFunction.functionType() == CSSValueMatrix3d) {
        lengthArray.typeFlags.set(CSSPrimitiveValue::UnitTypePixels);
        continue;
      }
      for (const CSSValue* argument : transformFunction) {
        const CSSPrimitiveValue& primitiveValue =
            toCSSPrimitiveValue(*argument);
        if (!primitiveValue.isLength())
          continue;
        primitiveValue.accumulateLengthArray(lengthArray);
      }
    }
    std::unique_ptr<InterpolationType::ConversionChecker> lengthUnitsChecker =
        LengthUnitsChecker::maybeCreate(std::move(lengthArray), state);

    if (lengthUnitsChecker)
      conversionCheckers.append(std::move(lengthUnitsChecker));
  }

  TransformOperations transform;
  TransformBuilder::createTransformOperations(
      value, state.cssToLengthConversionData(), transform);
  return convertTransform(std::move(transform));
}
bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSValue& value)
{
    switch (value.cssValueType()) {
    case CSSValue::CSS_INHERIT:
        return true;
    case CSSValue::CSS_PRIMITIVE_VALUE:
        return interpolationRequiresStyleResolve(toCSSPrimitiveValue(value));
    case CSSValue::CSS_VALUE_LIST:
        return interpolationRequiresStyleResolve(toCSSValueList(value));
    case CSSValue::CSS_CUSTOM:
        if (value.isImageValue())
            return interpolationRequiresStyleResolve(toCSSImageValue(value));
        if (value.isShadowValue())
            return interpolationRequiresStyleResolve(toCSSShadowValue(value));
        if (value.isSVGDocumentValue())
            return interpolationRequiresStyleResolve(toCSSSVGDocumentValue(value));
        // FIXME: consider other custom types.
        return true;
    case CSSValue::CSS_INITIAL:
        // FIXME: should not require resolving styles for initial.
        return true;
    default:
        ASSERT_NOT_REACHED();
        return true;
    }
}
void StyleBuilderFunctions::applyValueCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state, CSSValue* value)
{
    if (value->isValueList()) {
        CSSValueList* list = toCSSValueList(value);
        ASSERT(list->length() == 2);
        for (unsigned i = 0; i < 2; ++i) {
            CSSPrimitiveValue* value = toCSSPrimitiveValue(list->item(i));
            if (value->getValueID() == CSSValueFilled || value->getValueID() == CSSValueOpen)
                state.style()->setTextEmphasisFill(*value);
            else
                state.style()->setTextEmphasisMark(*value);
        }
        state.style()->setTextEmphasisCustomMark(nullAtom);
        return;
    }

    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);

    if (primitiveValue->isString()) {
        state.style()->setTextEmphasisFill(TextEmphasisFillFilled);
        state.style()->setTextEmphasisMark(TextEmphasisMarkCustom);
        state.style()->setTextEmphasisCustomMark(AtomicString(primitiveValue->getStringValue()));
        return;
    }

    state.style()->setTextEmphasisCustomMark(nullAtom);

    if (primitiveValue->getValueID() == CSSValueFilled || primitiveValue->getValueID() == CSSValueOpen) {
        state.style()->setTextEmphasisFill(*primitiveValue);
        state.style()->setTextEmphasisMark(TextEmphasisMarkAuto);
    } else {
        state.style()->setTextEmphasisFill(TextEmphasisFillFilled);
        state.style()->setTextEmphasisMark(*primitiveValue);
    }
}
bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSValue& value)
{
    // FIXME: should not require resolving styles for inherit/initial/unset.
    if (value.isCSSWideKeyword())
        return true;
    if (value.isBasicShapeCircleValue())
        return interpolationRequiresStyleResolve(toCSSBasicShapeCircleValue(value));
    if (value.isBasicShapeEllipseValue())
        return interpolationRequiresStyleResolve(toCSSBasicShapeEllipseValue(value));
    if (value.isBasicShapePolygonValue())
        return interpolationRequiresStyleResolve(toCSSBasicShapePolygonValue(value));
    if (value.isBasicShapeInsetValue())
        return interpolationRequiresStyleResolve(toCSSBasicShapeInsetValue(value));
    if (value.isPrimitiveValue())
        return interpolationRequiresStyleResolve(toCSSPrimitiveValue(value));
    if (value.isQuadValue())
        return interpolationRequiresStyleResolve(toCSSQuadValue(value));
    if (value.isValueList())
        return interpolationRequiresStyleResolve(toCSSValueList(value));
    if (value.isValuePair())
        return interpolationRequiresStyleResolve(toCSSValuePair(value));
    if (value.isImageValue())
        return interpolationRequiresStyleResolve(toCSSImageValue(value));
    if (value.isShadowValue())
        return interpolationRequiresStyleResolve(toCSSShadowValue(value));
    if (value.isSVGDocumentValue())
        return interpolationRequiresStyleResolve(toCSSSVGDocumentValue(value));
    // FIXME: consider other custom types.
    return true;
}
Ejemplo n.º 10
0
InterpolationValue CSSFilterListInterpolationType::maybeConvertValue(
    const CSSValue& value,
    const StyleResolverState&,
    ConversionCheckers&) const {
  if (value.isIdentifierValue() &&
      toCSSIdentifierValue(value).getValueID() == CSSValueNone)
    return InterpolationValue(InterpolableList::create(0),
                              NonInterpolableList::create());

  if (!value.isBaseValueList())
    return nullptr;

  const CSSValueList& list = toCSSValueList(value);
  size_t length = list.length();
  std::unique_ptr<InterpolableList> interpolableList =
      InterpolableList::create(length);
  Vector<RefPtr<NonInterpolableValue>> nonInterpolableValues(length);
  for (size_t i = 0; i < length; i++) {
    InterpolationValue itemResult =
        FilterInterpolationFunctions::maybeConvertCSSFilter(list.item(i));
    if (!itemResult)
      return nullptr;
    interpolableList->set(i, std::move(itemResult.interpolableValue));
    nonInterpolableValues[i] = itemResult.nonInterpolableValue.release();
  }
  return InterpolationValue(
      std::move(interpolableList),
      NonInterpolableList::create(std::move(nonInterpolableValues)));
}
TEST(CSSPropertyParserTest, GridTrackLimits)
{
    struct {
        const CSSPropertyID propertyID;
        const char* input;
        const size_t output;
    } testCases[] = {
        {CSSPropertyGridTemplateColumns, "repeat(999999, 20px)", 999999},
        {CSSPropertyGridTemplateRows, "repeat(999999, 20px)", 999999},
        {CSSPropertyGridTemplateColumns, "repeat(1000000, 10%)", 1000000},
        {CSSPropertyGridTemplateRows, "repeat(1000000, 10%)", 1000000},
        {CSSPropertyGridTemplateColumns, "repeat(1000000, (first) min-content (last))", 1000000},
        {CSSPropertyGridTemplateRows, "repeat(1000000, (first) min-content (last))", 1000000},
        {CSSPropertyGridTemplateColumns, "repeat(1000001, auto)", 1000000},
        {CSSPropertyGridTemplateRows, "repeat(1000001, auto)", 1000000},
        {CSSPropertyGridTemplateColumns, "repeat(400000, 2em minmax(10px, max-content) 0.5fr)", 999999},
        {CSSPropertyGridTemplateRows, "repeat(400000, 2em minmax(10px, max-content) 0.5fr)", 999999},
        {CSSPropertyGridTemplateColumns, "repeat(600000, (first) 3vh 10% 2fr (nav) 10px auto 1fr 6em (last))", 999999},
        {CSSPropertyGridTemplateRows, "repeat(600000, (first) 3vh 10% 2fr (nav) 10px auto 1fr 6em (last))", 999999},
        {CSSPropertyGridTemplateColumns, "repeat(100000000000000000000, 10% 1fr)", 1000000},
        {CSSPropertyGridTemplateRows, "repeat(100000000000000000000, 10% 1fr)", 1000000},
        {CSSPropertyGridTemplateColumns, "repeat(100000000000000000000, 10% 5em 1fr auto auto 15px min-content)", 999999},
        {CSSPropertyGridTemplateRows, "repeat(100000000000000000000, 10% 5em 1fr auto auto 15px min-content)", 999999},
    };

    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(testCases); ++i) {
        RefPtrWillBeRawPtr<CSSValue> value = CSSParser::parseSingleValue(testCases[i].propertyID, testCases[i].input);
        ASSERT_TRUE(value);
        ASSERT_TRUE(value->isValueList());
        EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value.get())), testCases[i].output);
    }
}
Ejemplo n.º 12
0
void FontFace::initCSSFontFace(Document* document, PassRefPtrWillBeRawPtr<CSSValue> src)
{
    m_cssFontFace = createCSSFontFace(this, m_unicodeRange.get());
    if (m_error)
        return;

    // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace.
    ASSERT(src);
    ASSERT(src->isValueList());
    CSSValueList* srcList = toCSSValueList(src.get());
    int srcLength = srcList->length();

    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->item(i));
        OwnPtrWillBeRawPtr<CSSFontFaceSource> source = nullptr;

        if (!item->isLocal()) {
            const Settings* settings = document ? document->settings() : nullptr;
            bool allowDownloading = settings && settings->downloadableBinaryFontsEnabled();
            if (allowDownloading && item->isSupportedFormat() && document) {
                FontResource* fetched = item->fetch(document);
                if (fetched) {
                    FontLoader* fontLoader = document->styleEngine().fontSelector()->fontLoader();
                    source = adoptPtrWillBeNoop(new RemoteFontFaceSource(fetched, fontLoader));
                }
            }
        } else {
            source = adoptPtrWillBeNoop(new LocalFontFaceSource(item->resource()));
        }

        if (source)
            m_cssFontFace->addSource(source.release());
    }
}
void StyleBuilderFunctions::applyValueCSSPropertyMotionRotation(StyleResolverState& state, CSSValue* value)
{
    float rotation = 0;
    MotionRotationType rotationType = MotionRotationFixed;

    ASSERT(value->isValueList());
    CSSValueList* list = toCSSValueList(value);
    int len = list->length();
    for (int i = 0; i < len; i++) {
        CSSValue* item = list->item(i);
        ASSERT(item->isPrimitiveValue());
        CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(item);
        if (primitiveValue->getValueID() == CSSValueAuto) {
            rotationType = MotionRotationAuto;
        } else if (primitiveValue->getValueID() == CSSValueReverse) {
            rotationType = MotionRotationAuto;
            rotation += 180;
        } else {
            rotation += primitiveValue->computeDegrees();
        }
    }

    state.style()->setMotionRotation(rotation);
    state.style()->setMotionRotationType(rotationType);
}
PassRefPtr<ShadowList> StyleBuilderConverter::convertShadow(StyleResolverState& state, CSSValue* value)
{
    if (value->isPrimitiveValue()) {
        ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
        return PassRefPtr<ShadowList>();
    }

    const CSSValueList* valueList = toCSSValueList(value);
    size_t shadowCount = valueList->length();
    ShadowDataVector shadows;
    for (size_t i = 0; i < shadowCount; ++i) {
        const CSSShadowValue* item = toCSSShadowValue(valueList->item(i));
        float x = item->x->computeLength<float>(state.cssToLengthConversionData());
        float y = item->y->computeLength<float>(state.cssToLengthConversionData());
        float blur = item->blur ? item->blur->computeLength<float>(state.cssToLengthConversionData()) : 0;
        float spread = item->spread ? item->spread->computeLength<float>(state.cssToLengthConversionData()) : 0;
        ShadowStyle shadowStyle = item->style && item->style->getValueID() == CSSValueInset ? Inset : Normal;
        Color color;
        if (item->color)
            color = convertColor(state, item->color.get());
        else
            color = state.style()->color();
        shadows.append(ShadowData(FloatPoint(x, y), blur, spread, shadowStyle, color));
    }
    return ShadowList::adopt(shadows);
}
Ejemplo n.º 15
0
void FontBuilder::setFontVariantLigaturesValue(CSSValue* value)
{
    FontDescriptionChangeScope scope(this);

    FontDescription::LigaturesState commonLigaturesState = FontDescription::NormalLigaturesState;
    FontDescription::LigaturesState discretionaryLigaturesState = FontDescription::NormalLigaturesState;
    FontDescription::LigaturesState historicalLigaturesState = FontDescription::NormalLigaturesState;
    FontDescription::LigaturesState contextualLigaturesState = FontDescription::NormalLigaturesState;

    if (value->isValueList()) {
        CSSValueList* valueList = toCSSValueList(value);
        for (size_t i = 0; i < valueList->length(); ++i) {
            CSSValue* item = valueList->itemWithoutBoundsCheck(i);
            ASSERT(item->isPrimitiveValue());
            if (item->isPrimitiveValue()) {
                CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(item);
                switch (primitiveValue->getValueID()) {
                case CSSValueNoCommonLigatures:
                    commonLigaturesState = FontDescription::DisabledLigaturesState;
                    break;
                case CSSValueCommonLigatures:
                    commonLigaturesState = FontDescription::EnabledLigaturesState;
                    break;
                case CSSValueNoDiscretionaryLigatures:
                    discretionaryLigaturesState = FontDescription::DisabledLigaturesState;
                    break;
                case CSSValueDiscretionaryLigatures:
                    discretionaryLigaturesState = FontDescription::EnabledLigaturesState;
                    break;
                case CSSValueNoHistoricalLigatures:
                    historicalLigaturesState = FontDescription::DisabledLigaturesState;
                    break;
                case CSSValueHistoricalLigatures:
                    historicalLigaturesState = FontDescription::EnabledLigaturesState;
                    break;
                case CSSValueNoContextual:
                    contextualLigaturesState = FontDescription::DisabledLigaturesState;
                    break;
                case CSSValueContextual:
                    contextualLigaturesState = FontDescription::EnabledLigaturesState;
                    break;
                default:
                    ASSERT_NOT_REACHED();
                    break;
                }
            }
        }
    }
#if ASSERT_ENABLED
    else {
        ASSERT_WITH_SECURITY_IMPLICATION(value->isPrimitiveValue());
        ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNormal);
    }
#endif

    scope.fontDescription().setCommonLigaturesState(commonLigaturesState);
    scope.fontDescription().setDiscretionaryLigaturesState(discretionaryLigaturesState);
    scope.fontDescription().setHistoricalLigaturesState(historicalLigaturesState);
    scope.fontDescription().setContextualLigaturesState(contextualLigaturesState);
}
Ejemplo n.º 16
0
PassRefPtr<FontFace> FontFace::create(Document* document, const StyleRuleFontFace* fontFaceRule)
{
    const StylePropertySet& properties = fontFaceRule->properties();

    // Obtain the font-family property and the src property. Both must be defined.
    RefPtrWillBeRawPtr<CSSValue> family = properties.getPropertyCSSValue(CSSPropertyFontFamily);
    if (!family || !family->isValueList())
        return nullptr;
    RefPtrWillBeRawPtr<CSSValue> src = properties.getPropertyCSSValue(CSSPropertySrc);
    if (!src || !src->isValueList())
        return nullptr;

    RefPtr<FontFace> fontFace = adoptRefWillBeRefCountedGarbageCollected<FontFace>(new FontFace());

    if (fontFace->setFamilyValue(toCSSValueList(family.get()))
        && fontFace->setPropertyFromStyle(properties, CSSPropertyFontStyle)
        && fontFace->setPropertyFromStyle(properties, CSSPropertyFontWeight)
        && fontFace->setPropertyFromStyle(properties, CSSPropertyFontStretch)
        && fontFace->setPropertyFromStyle(properties, CSSPropertyUnicodeRange)
        && fontFace->setPropertyFromStyle(properties, CSSPropertyFontVariant)
        && fontFace->setPropertyFromStyle(properties, CSSPropertyWebkitFontFeatureSettings)
        && !fontFace->family().isEmpty()
        && fontFace->traits().mask()) {
        fontFace->initCSSFontFace(document, src);
        return fontFace.release();
    }
    return nullptr;
}
Ejemplo n.º 17
0
void FontFace::initCSSFontFace(Document* document, PassRefPtrWillBeRawPtr<CSSValue> src)
{
    m_cssFontFace = createCSSFontFace(this, m_unicodeRange.get());
    if (m_error)
        return;

    // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace.
    ASSERT(src);
    ASSERT(src->isValueList());
    CSSValueList* srcList = toCSSValueList(src.get());
    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->item(i));
        OwnPtrWillBeRawPtr<CSSFontFaceSource> source = nullptr;

#if ENABLE(SVG_FONTS)
        foundSVGFont = item->isSVGFontFaceSrc() || item->svgFontFaceElement();
#endif
        if (!item->isLocal()) {
            Settings* settings = document ? document->frame() ? document->frame()->settings() : 0 : 0;
            bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled());
            if (allowDownloading && item->isSupportedFormat() && document) {
                FontResource* fetched = item->fetch(document);
                if (fetched) {
                    FontLoader* fontLoader = document->styleEngine()->fontSelector()->fontLoader();

#if ENABLE(SVG_FONTS)
                    if (foundSVGFont) {
                        source = adoptPtrWillBeNoop(new SVGRemoteFontFaceSource(item->resource(), fetched, fontLoader));
                    } else
#endif
                    {
                        source = adoptPtrWillBeNoop(new RemoteFontFaceSource(fetched, fontLoader));
                    }
                }
            }
        } else {
#if ENABLE(SVG_FONTS)
            if (item->svgFontFaceElement()) {
                RefPtrWillBeRawPtr<SVGFontFaceElement> fontfaceElement = item->svgFontFaceElement();
                // SVGFontFaceSource assumes that it is the case where <font-face> element resides in the same document.
                // We put a RELEASE_ASSERT here as it will cause UAF if the assumption is false.
                RELEASE_ASSERT(fontfaceElement->inDocument());
                RELEASE_ASSERT(fontfaceElement->document() == document);
                source = adoptPtrWillBeNoop(new SVGFontFaceSource(fontfaceElement.get()));
            } else
#endif
            {
                source = adoptPtrWillBeNoop(new LocalFontFaceSource(item->resource()));
            }
        }

        if (source)
            m_cssFontFace->addSource(source.release());
    }
}
Ejemplo n.º 18
0
String CSSValue::cssText() const
{
    if (m_isTextClone) {
         ASSERT(isCSSOMSafe());
        return toTextCloneCSSValue(this)->cssText();
    }
    ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());

    switch (classType()) {
    case AspectRatioClass:
        return toCSSAspectRatioValue(this)->customCSSText();
    case BorderImageSliceClass:
        return toCSSBorderImageSliceValue(this)->customCSSText();
    case FontClass:
        return toCSSFontValue(this)->customCSSText();
    case FontFaceSrcClass:
        return toCSSFontFaceSrcValue(this)->customCSSText();
    case FontFeatureClass:
        return toCSSFontFeatureValue(this)->customCSSText();
    case FunctionClass:
        return toCSSFunctionValue(this)->customCSSText();
    case LinearGradientClass:
        return toCSSLinearGradientValue(this)->customCSSText();
    case RadialGradientClass:
        return toCSSRadialGradientValue(this)->customCSSText();
    case CrossfadeClass:
        return toCSSCrossfadeValue(this)->customCSSText();
    case ImageClass:
        return toCSSImageValue(this)->customCSSText();
    case InheritedClass:
        return toCSSInheritedValue(this)->customCSSText();
    case InitialClass:
        return toCSSInitialValue(this)->customCSSText();
    case PrimitiveClass:
        return toCSSPrimitiveValue(this)->customCSSText();
    case ShadowClass:
        return toCSSShadowValue(this)->customCSSText();
    case CubicBezierTimingFunctionClass:
        return toCSSCubicBezierTimingFunctionValue(this)->customCSSText();
    case StepsTimingFunctionClass:
        return toCSSStepsTimingFunctionValue(this)->customCSSText();
    case UnicodeRangeClass:
        return toCSSUnicodeRangeValue(this)->customCSSText();
    case ValueListClass:
        return toCSSValueList(this)->customCSSText();
    case CSSTransformClass:
        return toCSSTransformValue(this)->customCSSText();
    case LineBoxContainClass:
        return toCSSLineBoxContainValue(this)->customCSSText();
    case CalculationClass:
        return toCSSCalcValue(this)->customCSSText();
    case ImageSetClass:
        return toCSSImageSetValue(this)->customCSSText();
    case CSSFilterClass:
        return toCSSFilterValue(this)->customCSSText();
    }
    ASSERT_NOT_REACHED();
    return String();
}
InterpolationValue CSSBasicShapeInterpolationType::maybeConvertValue(const CSSValue& value, const StyleResolverState&, ConversionCheckers&) const
{
    if (!value.isBaseValueList())
        return BasicShapeInterpolationFunctions::maybeConvertCSSValue(value);

    const CSSValueList& list = toCSSValueList(value);
    if (list.length() != 1)
        return nullptr;
    return BasicShapeInterpolationFunctions::maybeConvertCSSValue(*list.item(0));
}
InterpolationValue CSSLengthListInterpolationType::maybeConvertValue(const CSSValue& value, const StyleResolverState&, ConversionCheckers&) const
{
    if (!value.isBaseValueList())
        return nullptr;

    const CSSValueList& list = toCSSValueList(value);
    return ListInterpolationFunctions::createList(list.length(), [&list](size_t index) {
        return CSSLengthInterpolationType::maybeConvertCSSValue(*list.item(index));
    });
}
GridPosition StyleBuilderConverter::convertGridPosition(StyleResolverState&, CSSValue* value)
{
    // We accept the specification's grammar:
    // 'auto' | [ <integer> || <custom-ident> ] | [ span && [ <integer> || <custom-ident> ] ] | <custom-ident>

    GridPosition position;

    if (value->isPrimitiveValue()) {
        CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
        // We translate <custom-ident> to <string> during parsing as it
        // makes handling it more simple.
        if (primitiveValue->isString()) {
            position.setNamedGridArea(primitiveValue->getStringValue());
            return position;
        }

        ASSERT(primitiveValue->getValueID() == CSSValueAuto);
        return position;
    }

    CSSValueList* values = toCSSValueList(value);
    ASSERT(values->length());

    bool isSpanPosition = false;
    // The specification makes the <integer> optional, in which case it default to '1'.
    int gridLineNumber = 1;
    String gridLineName;

    CSSValueListIterator it = values;
    CSSPrimitiveValue* currentValue = toCSSPrimitiveValue(it.value());
    if (currentValue->getValueID() == CSSValueSpan) {
        isSpanPosition = true;
        it.advance();
        currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
    }

    if (currentValue && currentValue->isNumber()) {
        gridLineNumber = currentValue->getIntValue();
        it.advance();
        currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
    }

    if (currentValue && currentValue->isString()) {
        gridLineName = currentValue->getStringValue();
        it.advance();
    }

    ASSERT(!it.hasMore());
    if (isSpanPosition)
        position.setSpanPosition(gridLineNumber, gridLineName);
    else
        position.setExplicitPosition(gridLineNumber, gridLineName);

    return position;
}
Ejemplo n.º 22
0
String StylePropertySerializer::backgroundRepeatPropertyValue() const
{
    RefPtr<CSSValue> repeatX = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundRepeatX);
    RefPtr<CSSValue> repeatY = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundRepeatY);
    if (!repeatX || !repeatY)
        return String();
    if (repeatX->cssValueType() == repeatY->cssValueType()
        && (repeatX->cssValueType() == CSSValue::CSS_INITIAL || repeatX->cssValueType() == CSSValue::CSS_INHERIT)) {
        return repeatX->cssText();
    }

    RefPtr<CSSValueList> repeatXList;
    if (repeatX->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) {
        repeatXList = CSSValueList::createCommaSeparated();
        repeatXList->append(repeatX);
    } else if (repeatX->cssValueType() == CSSValue::CSS_VALUE_LIST) {
        repeatXList = toCSSValueList(repeatX.get());
    } else {
        return String();
    }

    RefPtr<CSSValueList> repeatYList;
    if (repeatY->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) {
        repeatYList = CSSValueList::createCommaSeparated();
        repeatYList->append(repeatY);
    } else if (repeatY->cssValueType() == CSSValue::CSS_VALUE_LIST) {
        repeatYList = toCSSValueList(repeatY.get());
    } else {
        return String();
    }

    size_t shorthandLength = lowestCommonMultiple(repeatXList->length(), repeatYList->length());
    StringBuilder builder;
    for (size_t i = 0; i < shorthandLength; ++i) {
        if (i)
            builder.appendLiteral(", ");
        appendBackgroundRepeatValue(builder,
            *repeatXList->item(i % repeatXList->length()),
            *repeatYList->item(i % repeatYList->length()));
    }
    return builder.toString();
}
void StyleBuilderFunctions::applyValueCSSPropertySize(StyleResolverState& state, CSSValue* value)
{
    state.style()->resetPageSizeType();
    FloatSize size;
    PageSizeType pageSizeType = PAGE_SIZE_AUTO;
    CSSValueList* list = toCSSValueList(value);
    if (list->length() == 2) {
        // <length>{2} | <page-size> <orientation>
        CSSPrimitiveValue* first = toCSSPrimitiveValue(list->item(0));
        CSSPrimitiveValue* second = toCSSPrimitiveValue(list->item(1));
        if (first->isLength()) {
            // <length>{2}
            size = FloatSize(first->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0)),
                second->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0)));
        } else {
            // <page-size> <orientation>
            size = getPageSizeFromName(first);

            ASSERT(second->getValueID() == CSSValueLandscape || second->getValueID() == CSSValuePortrait);
            if (second->getValueID() == CSSValueLandscape)
                size = size.transposedSize();
        }
        pageSizeType = PAGE_SIZE_RESOLVED;
    } else {
        ASSERT(list->length() == 1);
        // <length> | auto | <page-size> | [ portrait | landscape]
        CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0));
        if (primitiveValue->isLength()) {
            // <length>
            pageSizeType = PAGE_SIZE_RESOLVED;
            float width = primitiveValue->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0));
            size = FloatSize(width, width);
        } else {
            switch (primitiveValue->getValueID()) {
            case CSSValueAuto:
                pageSizeType = PAGE_SIZE_AUTO;
                break;
            case CSSValuePortrait:
                pageSizeType = PAGE_SIZE_AUTO_PORTRAIT;
                break;
            case CSSValueLandscape:
                pageSizeType = PAGE_SIZE_AUTO_LANDSCAPE;
                break;
            default:
                // <page-size>
                pageSizeType = PAGE_SIZE_RESOLVED;
                size = getPageSizeFromName(primitiveValue);
            }
        }
    }
    state.style()->setPageSizeType(pageSizeType);
    state.style()->setPageSize(size);
}
Ejemplo n.º 24
0
PassRefPtr<TimingFunction> AnimationInputHelpers::parseTimingFunction(const String& string)
{
    if (string.isEmpty())
        return nullptr;

    RefPtrWillBeRawPtr<CSSValue> value = CSSParser::parseSingleValue(CSSPropertyTransitionTimingFunction, string);
    if (!value || value->isInitialValue() || value->isInheritedValue())
        return nullptr;
    CSSValueList* valueList = toCSSValueList(value.get());
    if (valueList->length() > 1)
        return nullptr;
    return CSSToStyleMap::mapAnimationTimingFunction(valueList->item(0), true);
}
Ejemplo n.º 25
0
static CSSFontFace* createCSSFontFace(FontFace* fontFace, CSSValue* unicodeRange)
{
    Vector<UnicodeRange> ranges;
    if (CSSValueList* rangeList = toCSSValueList(unicodeRange)) {
        unsigned numRanges = rangeList->length();
        for (unsigned i = 0; i < numRanges; i++) {
            CSSUnicodeRangeValue* range = toCSSUnicodeRangeValue(rangeList->item(i));
            ranges.append(UnicodeRange(range->from(), range->to()));
        }
    }

    return new CSSFontFace(fontFace, ranges);
}
Ejemplo n.º 26
0
static PassOwnPtrWillBeRawPtr<CSSFontFace> createCSSFontFace(FontFace* fontFace, CSSValue* unicodeRange)
{
    Vector<CSSFontFace::UnicodeRange> ranges;
    if (CSSValueList* rangeList = toCSSValueList(unicodeRange)) {
        unsigned numRanges = rangeList->length();
        for (unsigned i = 0; i < numRanges; i++) {
            CSSUnicodeRangeValue* range = toCSSUnicodeRangeValue(rangeList->item(i));
            ranges.append(CSSFontFace::UnicodeRange(range->from(), range->to()));
        }
    }

    return adoptPtrWillBeNoop(new CSSFontFace(fontFace, ranges));
}
Ejemplo n.º 27
0
v8::Handle<v8::Object> wrap(CSSValue* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
    ASSERT(impl);
    if (impl->isTransformValue())
        return wrap(toCSSTransformValue(impl), creationContext, isolate);
    if (impl->isFilterValue())
        return wrap(toCSSFilterValue(impl), creationContext, isolate);
    if (impl->isValueList())
        return wrap(toCSSValueList(impl), creationContext, isolate);
    if (impl->isPrimitiveValue())
        return wrap(toCSSPrimitiveValue(impl), creationContext, isolate);
    return V8CSSValue::createWrapper(impl, creationContext, isolate);
}
InterpolationValue CSSShadowListInterpolationType::maybeConvertValue(const CSSValue& value, const StyleResolverState&, ConversionCheckers&) const
{
    if (value.isPrimitiveValue() && toCSSPrimitiveValue(value).getValueID() == CSSValueNone)
        return createNeutralValue();

    if (!value.isBaseValueList())
        return nullptr;

    const CSSValueList& valueList = toCSSValueList(value);
    return ListInterpolationFunctions::createList(valueList.length(), [&valueList](size_t index) {
        return ShadowInterpolationFunctions::maybeConvertCSSValue(valueList.item(index));
    });
}
PassRefPtr<FontFeatureSettings> StyleBuilderConverter::convertFontFeatureSettings(StyleResolverState& state, CSSValue* value)
{
    if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNormal)
        return FontBuilder::initialFeatureSettings();

    CSSValueList* list = toCSSValueList(value);
    RefPtr<FontFeatureSettings> settings = FontFeatureSettings::create();
    int len = list->length();
    for (int i = 0; i < len; ++i) {
        CSSFontFeatureValue* feature = toCSSFontFeatureValue(list->item(i));
        settings->append(FontFeature(feature->tag(), feature->value()));
    }
    return settings;
}
    static void compareLengthLists(PassRefPtrWillBeRawPtr<CSSValueList> expectedList, PassRefPtrWillBeRawPtr<CSSValue> actualList)
    {
        ASSERT(actualList->isValueList());

        for (size_t i = 0; i < 10; i++) {
            CSSValue* currentExpectedValue = expectedList->item(i);
            CSSValue* currentActualValue = toCSSValueList(*actualList).item(i);
            ASSERT(currentExpectedValue->isPrimitiveValue());
            ASSERT(currentActualValue->isPrimitiveValue());

            EXPECT_EQ(toCSSPrimitiveValue(currentExpectedValue)->getDoubleValue(), toCSSPrimitiveValue(currentActualValue)->getDoubleValue());
            EXPECT_EQ(toCSSPrimitiveValue(currentExpectedValue)->getDoubleValue(), toCSSPrimitiveValue(currentActualValue)->getDoubleValue());
        }
    }