Home | History | Annotate | Download | only in resolver
      1 /*
      2  * Copyright (C) 2013 Google Inc. All rights reserved.
      3  *
      4  *     * Redistributions of source code must retain the above copyright
      5  * notice, this list of conditions and the following disclaimer.
      6  *     * Redistributions in binary form must reproduce the above
      7  * copyright notice, this list of conditions and the following disclaimer
      8  * in the documentation and/or other materials provided with the
      9  * distribution.
     10  *     * Neither the name of Google Inc. nor the names of its
     11  * contributors may be used to endorse or promote products derived from
     12  * this software without specific prior written permission.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     15  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     16  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     17  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     18  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     19  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     20  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "config.h"
     28 #include "core/css/resolver/StyleBuilderConverter.h"
     29 
     30 #include "core/css/CSSPrimitiveValueMappings.h"
     31 #include "core/css/CSSShadowValue.h"
     32 #include "core/css/Pair.h"
     33 #include "core/svg/SVGURIReference.h"
     34 
     35 namespace WebCore {
     36 
     37 String StyleBuilderConverter::convertFragmentIdentifier(StyleResolverState& state, CSSValue* value)
     38 {
     39     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
     40     if (primitiveValue->isURI())
     41         return SVGURIReference::fragmentIdentifierFromIRIString(primitiveValue->getStringValue(), state.document());
     42     return String();
     43 }
     44 
     45 Length StyleBuilderConverter::convertLength(StyleResolverState& state, CSSValue* value)
     46 {
     47     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
     48     Length result = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
     49     ASSERT(!result.isUndefined());
     50     result.setQuirk(primitiveValue->isQuirkValue());
     51     return result;
     52 }
     53 
     54 Length StyleBuilderConverter::convertLengthOrAuto(StyleResolverState& state, CSSValue* value)
     55 {
     56     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
     57     Length result = primitiveValue->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData());
     58     ASSERT(!result.isUndefined());
     59     result.setQuirk(primitiveValue->isQuirkValue());
     60     return result;
     61 }
     62 
     63 Length StyleBuilderConverter::convertLengthSizing(StyleResolverState& state, CSSValue* value)
     64 {
     65     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
     66     switch (primitiveValue->getValueID()) {
     67     case CSSValueInvalid:
     68         return convertLength(state, value);
     69     case CSSValueIntrinsic:
     70         return Length(Intrinsic);
     71     case CSSValueMinIntrinsic:
     72         return Length(MinIntrinsic);
     73     case CSSValueWebkitMinContent:
     74         return Length(MinContent);
     75     case CSSValueWebkitMaxContent:
     76         return Length(MaxContent);
     77     case CSSValueWebkitFillAvailable:
     78         return Length(FillAvailable);
     79     case CSSValueWebkitFitContent:
     80         return Length(FitContent);
     81     case CSSValueAuto:
     82         return Length(Auto);
     83     default:
     84         ASSERT_NOT_REACHED();
     85         return Length();
     86     }
     87 }
     88 
     89 Length StyleBuilderConverter::convertLengthMaxSizing(StyleResolverState& state, CSSValue* value)
     90 {
     91     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
     92     if (primitiveValue->getValueID() == CSSValueNone)
     93         return Length(Undefined);
     94     return convertLengthSizing(state, value);
     95 }
     96 
     97 LengthPoint StyleBuilderConverter::convertLengthPoint(StyleResolverState& state, CSSValue* value)
     98 {
     99     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    100     Pair* pair = primitiveValue->getPairValue();
    101     Length x = pair->first()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
    102     Length y = pair->second()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
    103     return LengthPoint(x, y);
    104 }
    105 
    106 float StyleBuilderConverter::convertNumberOrPercentage(StyleResolverState& state, CSSValue* value)
    107 {
    108     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    109     ASSERT(primitiveValue->isNumber() || primitiveValue->isPercentage());
    110     if (primitiveValue->isNumber())
    111         return primitiveValue->getFloatValue();
    112     return primitiveValue->getFloatValue() / 100.0f;
    113 }
    114 
    115 LengthSize StyleBuilderConverter::convertRadius(StyleResolverState& state, CSSValue* value)
    116 {
    117     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    118     Pair* pair = primitiveValue->getPairValue();
    119     Length radiusWidth = pair->first()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
    120     Length radiusHeight = pair->second()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
    121     float width = radiusWidth.value();
    122     float height = radiusHeight.value();
    123     ASSERT(width >= 0 && height >= 0);
    124     if (width <= 0 || height <= 0)
    125         return LengthSize(Length(0, Fixed), Length(0, Fixed));
    126     return LengthSize(radiusWidth, radiusHeight);
    127 }
    128 
    129 PassRefPtr<ShadowList> StyleBuilderConverter::convertShadow(StyleResolverState& state, CSSValue* value)
    130 {
    131     if (value->isPrimitiveValue()) {
    132         ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
    133         return PassRefPtr<ShadowList>();
    134     }
    135 
    136     const CSSValueList* valueList = toCSSValueList(value);
    137     size_t shadowCount = valueList->length();
    138     ShadowDataVector shadows;
    139     for (size_t i = 0; i < shadowCount; ++i) {
    140         const CSSShadowValue* item = toCSSShadowValue(valueList->item(i));
    141         int x = item->x->computeLength<int>(state.cssToLengthConversionData());
    142         int y = item->y->computeLength<int>(state.cssToLengthConversionData());
    143         int blur = item->blur ? item->blur->computeLength<int>(state.cssToLengthConversionData()) : 0;
    144         int spread = item->spread ? item->spread->computeLength<int>(state.cssToLengthConversionData()) : 0;
    145         ShadowStyle shadowStyle = item->style && item->style->getValueID() == CSSValueInset ? Inset : Normal;
    146         Color color;
    147         if (item->color)
    148             color = state.document().textLinkColors().colorFromPrimitiveValue(item->color.get(), state.style()->color());
    149         else
    150             color = state.style()->color();
    151 
    152         if (!color.isValid())
    153             color = Color::transparent;
    154         shadows.append(ShadowData(IntPoint(x, y), blur, spread, shadowStyle, color));
    155     }
    156     return ShadowList::adopt(shadows);
    157 }
    158 
    159 float StyleBuilderConverter::convertSpacing(StyleResolverState& state, CSSValue* value)
    160 {
    161     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    162     if (primitiveValue->getValueID() == CSSValueNormal)
    163         return 0;
    164     if (state.useSVGZoomRules())
    165         return primitiveValue->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1));
    166     return primitiveValue->computeLength<float>(state.cssToLengthConversionData());
    167 }
    168 
    169 SVGLength StyleBuilderConverter::convertSVGLength(StyleResolverState&, CSSValue* value)
    170 {
    171     return SVGLength::fromCSSPrimitiveValue(toCSSPrimitiveValue(value));
    172 }
    173 
    174 } // namespace WebCore
    175