Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp

Issue 2326633002: Adds filter support for offscreen canvas (Closed)
Patch Set: Sync Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 // For offscreen canvas, the default color is always black.
276 if (shadow.color().isCurrentColor()) {
277 shadow.overrideColor(Color::black);
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698