OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) |
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) | 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) |
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. | 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. |
6 * All rights reserved. | 6 * All rights reserved. |
7 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 7 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
8 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> | 8 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> |
9 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 9 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
10 * (http://www.torchmobile.com/) | 10 * (http://www.torchmobile.com/) |
(...skipping 21 matching lines...) Expand all Loading... | |
32 | 32 |
33 #include "core/css/CSSFunctionValue.h" | 33 #include "core/css/CSSFunctionValue.h" |
34 #include "core/css/CSSPrimitiveValueMappings.h" | 34 #include "core/css/CSSPrimitiveValueMappings.h" |
35 #include "core/css/CSSURIValue.h" | 35 #include "core/css/CSSURIValue.h" |
36 #include "core/css/resolver/StyleBuilderConverter.h" | 36 #include "core/css/resolver/StyleBuilderConverter.h" |
37 #include "core/css/resolver/StyleResolverState.h" | 37 #include "core/css/resolver/StyleResolverState.h" |
38 #include "core/frame/UseCounter.h" | 38 #include "core/frame/UseCounter.h" |
39 | 39 |
40 namespace blink { | 40 namespace blink { |
41 | 41 |
42 static float kOffScreenCanvasEMFontSize = 10.0; | |
43 static float kOffScreenCanvasREMFontSize = 16.0; | |
44 | |
42 FilterOperation::OperationType FilterOperationResolver::filterOperationForType( | 45 FilterOperation::OperationType FilterOperationResolver::filterOperationForType( |
43 CSSValueID type) { | 46 CSSValueID type) { |
44 switch (type) { | 47 switch (type) { |
45 case CSSValueGrayscale: | 48 case CSSValueGrayscale: |
46 return FilterOperation::GRAYSCALE; | 49 return FilterOperation::GRAYSCALE; |
47 case CSSValueSepia: | 50 case CSSValueSepia: |
48 return FilterOperation::SEPIA; | 51 return FilterOperation::SEPIA; |
49 case CSSValueSaturate: | 52 case CSSValueSaturate: |
50 return FilterOperation::SATURATE; | 53 return FilterOperation::SATURATE; |
51 case CSSValueHueRotate: | 54 case CSSValueHueRotate: |
52 return FilterOperation::HUE_ROTATE; | 55 return FilterOperation::HUE_ROTATE; |
53 case CSSValueInvert: | 56 case CSSValueInvert: |
54 return FilterOperation::INVERT; | 57 return FilterOperation::INVERT; |
55 case CSSValueOpacity: | 58 case CSSValueOpacity: |
56 return FilterOperation::OPACITY; | 59 return FilterOperation::OPACITY; |
57 case CSSValueBrightness: | 60 case CSSValueBrightness: |
58 return FilterOperation::BRIGHTNESS; | 61 return FilterOperation::BRIGHTNESS; |
59 case CSSValueContrast: | 62 case CSSValueContrast: |
60 return FilterOperation::CONTRAST; | 63 return FilterOperation::CONTRAST; |
61 case CSSValueBlur: | 64 case CSSValueBlur: |
62 return FilterOperation::BLUR; | 65 return FilterOperation::BLUR; |
63 case CSSValueDropShadow: | 66 case CSSValueDropShadow: |
64 return FilterOperation::DROP_SHADOW; | 67 return FilterOperation::DROP_SHADOW; |
65 default: | 68 default: |
66 ASSERT_NOT_REACHED(); | 69 NOTREACHED(); |
67 // FIXME: We shouldn't have a type None since we never create them | 70 // FIXME: We shouldn't have a type None since we never create them |
68 return FilterOperation::NONE; | 71 return FilterOperation::NONE; |
69 } | 72 } |
70 } | 73 } |
71 | 74 |
72 static void countFilterUse(FilterOperation::OperationType operationType, | 75 static void countFilterUse(FilterOperation::OperationType operationType, |
73 const Document& document) { | 76 const Document& document) { |
74 // This variable is always reassigned, but MSVC thinks it might be left | 77 // This variable is always reassigned, but MSVC thinks it might be left |
75 // uninitialized. | 78 // uninitialized. |
76 UseCounter::Feature feature = UseCounter::NumberOfFeatures; | 79 UseCounter::Feature feature = UseCounter::NumberOfFeatures; |
77 switch (operationType) { | 80 switch (operationType) { |
78 case FilterOperation::NONE: | 81 case FilterOperation::NONE: |
79 case FilterOperation::BOX_REFLECT: | 82 case FilterOperation::BOX_REFLECT: |
80 ASSERT_NOT_REACHED(); | 83 NOTREACHED(); |
81 return; | 84 return; |
82 case FilterOperation::REFERENCE: | 85 case FilterOperation::REFERENCE: |
83 feature = UseCounter::CSSFilterReference; | 86 feature = UseCounter::CSSFilterReference; |
84 break; | 87 break; |
85 case FilterOperation::GRAYSCALE: | 88 case FilterOperation::GRAYSCALE: |
86 feature = UseCounter::CSSFilterGrayscale; | 89 feature = UseCounter::CSSFilterGrayscale; |
87 break; | 90 break; |
88 case FilterOperation::SEPIA: | 91 case FilterOperation::SEPIA: |
89 feature = UseCounter::CSSFilterSepia; | 92 feature = UseCounter::CSSFilterSepia; |
90 break; | 93 break; |
(...skipping 30 matching lines...) Expand all Loading... | |
121 const CSSValue& inValue) { | 124 const CSSValue& inValue) { |
122 FilterOperations operations; | 125 FilterOperations operations; |
123 | 126 |
124 if (inValue.isIdentifierValue()) { | 127 if (inValue.isIdentifierValue()) { |
125 DCHECK_EQ(toCSSIdentifierValue(inValue).getValueID(), CSSValueNone); | 128 DCHECK_EQ(toCSSIdentifierValue(inValue).getValueID(), CSSValueNone); |
126 return operations; | 129 return operations; |
127 } | 130 } |
128 | 131 |
129 const CSSToLengthConversionData& conversionData = | 132 const CSSToLengthConversionData& conversionData = |
130 state.cssToLengthConversionData(); | 133 state.cssToLengthConversionData(); |
134 | |
131 for (auto& currValue : toCSSValueList(inValue)) { | 135 for (auto& currValue : toCSSValueList(inValue)) { |
132 if (currValue->isURIValue()) { | 136 if (currValue->isURIValue()) { |
133 countFilterUse(FilterOperation::REFERENCE, state.document()); | 137 countFilterUse(FilterOperation::REFERENCE, state.document()); |
134 | 138 |
135 const CSSURIValue& urlValue = toCSSURIValue(*currValue); | 139 const CSSURIValue& urlValue = toCSSURIValue(*currValue); |
136 SVGElementProxy& elementProxy = | 140 SVGElementProxy& elementProxy = |
137 state.elementStyleResources().cachedOrPendingFromValue(urlValue); | 141 state.elementStyleResources().cachedOrPendingFromValue(urlValue); |
138 operations.operations().push_back( | 142 operations.operations().push_back( |
139 ReferenceFilterOperation::create(urlValue.value(), elementProxy)); | 143 ReferenceFilterOperation::create(urlValue.value(), elementProxy)); |
140 continue; | 144 continue; |
141 } | 145 } |
142 | 146 |
143 const CSSFunctionValue* filterValue = toCSSFunctionValue(currValue.get()); | 147 const CSSFunctionValue* filterValue = toCSSFunctionValue(currValue.get()); |
144 FilterOperation::OperationType operationType = | 148 FilterOperation::OperationType operationType = |
145 filterOperationForType(filterValue->functionType()); | 149 filterOperationForType(filterValue->functionType()); |
146 countFilterUse(operationType, state.document()); | 150 countFilterUse(operationType, state.document()); |
147 DCHECK_LE(filterValue->length(), 1u); | 151 DCHECK_LE(filterValue->length(), 1u); |
148 | 152 |
149 const CSSPrimitiveValue* firstValue = | 153 const CSSPrimitiveValue* firstValue = |
150 filterValue->length() && filterValue->item(0).isPrimitiveValue() | 154 filterValue->length() && filterValue->item(0).isPrimitiveValue() |
151 ? &toCSSPrimitiveValue(filterValue->item(0)) | 155 ? &toCSSPrimitiveValue(filterValue->item(0)) |
152 : nullptr; | 156 : nullptr; |
157 double firstNumber = | |
158 StyleBuilderConverter::convertValueToNumber(filterValue, firstValue); | |
159 | |
153 switch (filterValue->functionType()) { | 160 switch (filterValue->functionType()) { |
154 case CSSValueGrayscale: | 161 case CSSValueGrayscale: |
155 case CSSValueSepia: | 162 case CSSValueSepia: |
156 case CSSValueSaturate: { | 163 case CSSValueSaturate: |
157 double amount = 1; | 164 case CSSValueHueRotate: { |
158 if (filterValue->length() == 1) { | |
159 amount = firstValue->getDoubleValue(); | |
160 if (firstValue->isPercentage()) | |
161 amount /= 100; | |
162 } | |
163 | |
164 operations.operations().push_back( | 165 operations.operations().push_back( |
165 BasicColorMatrixFilterOperation::create(amount, operationType)); | 166 BasicColorMatrixFilterOperation::create(firstNumber, |
166 break; | 167 operationType)); |
167 } | |
168 case CSSValueHueRotate: { | |
169 double angle = 0; | |
170 if (filterValue->length() == 1) | |
171 angle = firstValue->computeDegrees(); | |
172 | |
173 operations.operations().push_back( | |
174 BasicColorMatrixFilterOperation::create(angle, operationType)); | |
175 break; | 168 break; |
176 } | 169 } |
177 case CSSValueInvert: | 170 case CSSValueInvert: |
178 case CSSValueBrightness: | 171 case CSSValueBrightness: |
179 case CSSValueContrast: | 172 case CSSValueContrast: |
180 case CSSValueOpacity: { | 173 case CSSValueOpacity: { |
181 double amount = | |
182 (filterValue->functionType() == CSSValueBrightness) ? 0 : 1; | |
183 if (filterValue->length() == 1) { | |
184 amount = firstValue->getDoubleValue(); | |
185 if (firstValue->isPercentage()) | |
186 amount /= 100; | |
187 } | |
188 | |
189 operations.operations().push_back( | 174 operations.operations().push_back( |
190 BasicComponentTransferFilterOperation::create(amount, | 175 BasicComponentTransferFilterOperation::create(firstNumber, |
191 operationType)); | 176 operationType)); |
192 break; | 177 break; |
193 } | 178 } |
194 case CSSValueBlur: { | 179 case CSSValueBlur: { |
195 Length stdDeviation = Length(0, Fixed); | 180 Length stdDeviation = Length(0, Fixed); |
196 if (filterValue->length() >= 1) | 181 if (filterValue->length() >= 1) { |
197 stdDeviation = firstValue->convertToLength(conversionData); | 182 stdDeviation = firstValue->convertToLength(conversionData); |
183 } | |
198 operations.operations().push_back( | 184 operations.operations().push_back( |
199 BlurFilterOperation::create(stdDeviation)); | 185 BlurFilterOperation::create(stdDeviation)); |
200 break; | 186 break; |
201 } | 187 } |
202 case CSSValueDropShadow: { | 188 case CSSValueDropShadow: { |
203 ShadowData shadow = | 189 ShadowData shadow = StyleBuilderConverter::convertShadow( |
204 StyleBuilderConverter::convertShadow(state, filterValue->item(0)); | 190 conversionData, &state, filterValue->item(0)); |
205 // TODO(fs): Resolve 'currentcolor' when constructing the filter chain. | 191 // TODO(fs): Resolve 'currentcolor' when constructing the filter chain. |
206 if (shadow.color().isCurrentColor()) | 192 if (shadow.color().isCurrentColor()) { |
207 shadow.overrideColor(state.style()->color()); | 193 shadow.overrideColor(state.style()->color()); |
194 } | |
208 operations.operations().push_back( | 195 operations.operations().push_back( |
209 DropShadowFilterOperation::create(shadow)); | 196 DropShadowFilterOperation::create(shadow)); |
210 break; | 197 break; |
211 } | 198 } |
212 default: | 199 default: |
213 ASSERT_NOT_REACHED(); | 200 NOTREACHED(); |
214 break; | 201 break; |
215 } | 202 } |
216 } | 203 } |
217 | 204 |
218 return operations; | 205 return operations; |
219 } | 206 } |
220 | 207 |
208 FilterOperations FilterOperationResolver::createOffscreenFilterOperations( | |
209 const CSSValue& inValue) { | |
210 FilterOperations operations; | |
211 | |
212 if (inValue.isIdentifierValue()) { | |
213 DCHECK_EQ(toCSSIdentifierValue(inValue).getValueID(), CSSValueNone); | |
214 return operations; | |
215 } | |
216 | |
217 FontDescription fontDescription; | |
218 Font font(fontDescription); | |
219 CSSToLengthConversionData::FontSizes fontSizes( | |
220 kOffScreenCanvasEMFontSize, kOffScreenCanvasREMFontSize, &font); | |
221 CSSToLengthConversionData::ViewportSize viewportSize(1024, 768); | |
222 CSSToLengthConversionData conversionData(&ComputedStyle::initialStyle(), | |
223 fontSizes, viewportSize, 1); | |
224 | |
225 for (auto& currValue : toCSSValueList(inValue)) { | |
226 if (currValue->isURIValue()) | |
227 continue; | |
228 | |
229 const CSSFunctionValue* filterValue = toCSSFunctionValue(currValue.get()); | |
230 FilterOperation::OperationType operationType = | |
231 filterOperationForType(filterValue->functionType()); | |
232 // TODO(fserb): Take an ExecutionContext argument to this function, | |
233 // so we can have workers using UseCounter as well. | |
234 // countFilterUse(operationType, state.document()); | |
235 DCHECK_LE(filterValue->length(), 1u); | |
236 | |
237 const CSSPrimitiveValue* firstValue = | |
238 filterValue->length() && filterValue->item(0).isPrimitiveValue() | |
239 ? &toCSSPrimitiveValue(filterValue->item(0)) | |
240 : nullptr; | |
241 double firstNumber = | |
242 StyleBuilderConverter::convertValueToNumber(filterValue, firstValue); | |
243 | |
244 switch (filterValue->functionType()) { | |
245 case CSSValueGrayscale: | |
246 case CSSValueSepia: | |
247 case CSSValueSaturate: | |
248 case CSSValueHueRotate: { | |
249 operations.operations().push_back( | |
250 BasicColorMatrixFilterOperation::create(firstNumber, | |
251 operationType)); | |
252 break; | |
253 } | |
254 case CSSValueInvert: | |
255 case CSSValueBrightness: | |
256 case CSSValueContrast: | |
257 case CSSValueOpacity: { | |
258 operations.operations().push_back( | |
259 BasicComponentTransferFilterOperation::create(firstNumber, | |
260 operationType)); | |
261 break; | |
262 } | |
263 case CSSValueBlur: { | |
264 Length stdDeviation = Length(0, Fixed); | |
265 if (filterValue->length() >= 1) { | |
266 stdDeviation = firstValue->convertToLength(conversionData); | |
267 } | |
268 operations.operations().push_back( | |
269 BlurFilterOperation::create(stdDeviation)); | |
270 break; | |
271 } | |
272 case CSSValueDropShadow: { | |
273 ShadowData shadow = StyleBuilderConverter::convertShadow( | |
274 conversionData, nullptr, filterValue->item(0)); | |
275 // TODO(fs): Resolve 'currentcolor' when constructing the filter chain. | |
276 if (shadow.color().isCurrentColor()) { | |
277 shadow.overrideColor(Color::black); | |
esprehn
2017/01/27 19:44:39
Is this a regression? It used to do ->color() and
fserb
2017/01/27 19:54:47
Well, on a regular document, you want the default
| |
278 } | |
279 operations.operations().push_back( | |
280 DropShadowFilterOperation::create(shadow)); | |
281 break; | |
282 } | |
283 default: | |
284 NOTREACHED(); | |
285 break; | |
286 } | |
287 } | |
288 return operations; | |
289 } | |
290 | |
221 } // namespace blink | 291 } // namespace blink |
OLD | NEW |