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