OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2013 Adobe Systems Inc. All rights reserved. | 2 * Copyright (C) 2013 Adobe Systems Inc. All rights reserved. |
3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 * Copyright (C) 2013 Google Inc. All rights reserved. |
4 * Copyright (C) 2011 Apple Inc. All rights reserved. | 4 * Copyright (C) 2011 Apple Inc. All rights reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
60 } | 60 } |
61 | 61 |
62 void ReferenceFilterBuilder::clearDocumentResourceReference(const FilterOperatio n* filterOperation) | 62 void ReferenceFilterBuilder::clearDocumentResourceReference(const FilterOperatio n* filterOperation) |
63 { | 63 { |
64 if (!documentResourceReferences) | 64 if (!documentResourceReferences) |
65 return; | 65 return; |
66 | 66 |
67 documentResourceReferences->remove(filterOperation); | 67 documentResourceReferences->remove(filterOperation); |
68 } | 68 } |
69 | 69 |
70 // Returns whether or not the SVGElement object contains a valid color-interpola tion-filters attribute | 70 // Returns the color-interpolation-filters property of the element. |
71 static bool getSVGElementColorSpace(SVGElement* svgElement, ColorSpace& cs) | 71 static EColorInterpolation colorInterpolationForElement(SVGElement& element, ECo lorInterpolation parentColorInterpolation) |
72 { | 72 { |
73 if (!svgElement) | 73 if (const LayoutObject* layoutObject = element.layoutObject()) |
74 return false; | 74 return layoutObject->styleRef().svgStyle().colorInterpolationFilters(); |
75 | 75 |
76 const LayoutObject* layoutObject = svgElement->layoutObject(); | 76 // Otherwise, try to determine the property value "manually" (used by extern al SVG files.) |
Stephen White
2015/04/29 21:20:41
Nit: a little strange to have "Otherwise, " here n
fs
2015/04/30 08:29:23
Replaced it with "No layout has been performed, ..
| |
77 const ComputedStyle* style = layoutObject ? layoutObject->style() : 0; | 77 if (const StylePropertySet* propertySet = element.presentationAttributeStyle ()) { |
78 const SVGComputedStyle* svgStyle = style ? &style->svgStyle() : 0; | 78 RefPtrWillBeRawPtr<CSSValue> cssValue = propertySet->getPropertyCSSValue (CSSPropertyColorInterpolationFilters); |
79 EColorInterpolation eColorInterpolation = CI_AUTO; | 79 if (cssValue && cssValue->isPrimitiveValue()) { |
80 if (svgStyle) { | |
81 // If a layout has been performed, then we can use the fast path to get this attribute | |
82 eColorInterpolation = svgStyle->colorInterpolationFilters(); | |
83 } else if (!svgElement->presentationAttributeStyle()) { | |
84 return false; | |
85 } else { | |
86 // Otherwise, use the slow path by using string comparison (used by exte rnal svg files) | |
87 RefPtrWillBeRawPtr<CSSValue> cssValue = svgElement->presentationAttribut eStyle()->getPropertyCSSValue(CSSPropertyColorInterpolationFilters); | |
88 if (cssValue.get() && cssValue->isPrimitiveValue()) { | |
89 const CSSPrimitiveValue& primitiveValue = *((CSSPrimitiveValue*)cssV alue.get()); | 80 const CSSPrimitiveValue& primitiveValue = *((CSSPrimitiveValue*)cssV alue.get()); |
90 eColorInterpolation = (EColorInterpolation)primitiveValue; | 81 return static_cast<EColorInterpolation>(primitiveValue); |
91 } else { | |
92 return false; | |
93 } | 82 } |
94 } | 83 } |
95 | 84 // 'auto' is the default (per Filter Effects), but since the property is |
96 switch (eColorInterpolation) { | 85 // inherited, propagate the parent's value. |
97 case CI_AUTO: | 86 return parentColorInterpolation; |
98 case CI_SRGB: | |
99 cs = ColorSpaceDeviceRGB; | |
100 break; | |
101 case CI_LINEARRGB: | |
102 cs = ColorSpaceLinearRGB; | |
103 break; | |
104 default: | |
105 return false; | |
106 } | |
107 | |
108 return true; | |
109 } | 87 } |
110 | 88 |
111 PassRefPtrWillBeRawPtr<FilterEffect> ReferenceFilterBuilder::build(Filter* paren tFilter, LayoutObject* layoutObject, FilterEffect* previousEffect, const Referen ceFilterOperation* filterOperation) | 89 PassRefPtrWillBeRawPtr<FilterEffect> ReferenceFilterBuilder::build(Filter* paren tFilter, LayoutObject& layoutObject, FilterEffect* previousEffect, const Referen ceFilterOperation& filterOperation) |
112 { | 90 { |
113 if (!layoutObject) | 91 TreeScope* treeScope = &layoutObject.node()->treeScope(); |
114 return nullptr; | |
115 | 92 |
116 TreeScope* treeScope = &layoutObject->node()->treeScope(); | 93 if (DocumentResourceReference* documentResourceRef = documentResourceReferen ce(&filterOperation)) { |
117 | |
118 if (DocumentResourceReference* documentResourceRef = documentResourceReferen ce(filterOperation)) { | |
119 DocumentResource* cachedSVGDocument = documentResourceRef->document(); | 94 DocumentResource* cachedSVGDocument = documentResourceRef->document(); |
120 | 95 |
121 // If we have an SVG document, this is an external reference. Otherwise | 96 // If we have an SVG document, this is an external reference. Otherwise |
122 // we look up the referenced node in the current document. | 97 // we look up the referenced node in the current document. |
123 if (cachedSVGDocument) | 98 if (cachedSVGDocument) |
124 treeScope = cachedSVGDocument->document(); | 99 treeScope = cachedSVGDocument->document(); |
125 } | 100 } |
126 | 101 |
127 if (!treeScope) | 102 if (!treeScope) |
128 return nullptr; | 103 return nullptr; |
129 | 104 |
130 Element* filter = treeScope->getElementById(filterOperation->fragment()); | 105 Element* filter = treeScope->getElementById(filterOperation.fragment()); |
131 | 106 |
132 if (!filter) { | 107 if (!filter) { |
133 // Although we did not find the referenced filter, it might exist later | 108 // Although we did not find the referenced filter, it might exist later |
134 // in the document. | 109 // in the document. |
135 treeScope->document().accessSVGExtensions().addPendingResource(filterOpe ration->fragment(), toElement(layoutObject->node())); | 110 treeScope->document().accessSVGExtensions().addPendingResource(filterOpe ration.fragment(), toElement(layoutObject.node())); |
136 return nullptr; | 111 return nullptr; |
137 } | 112 } |
138 | 113 |
139 if (!isSVGFilterElement(*filter)) | 114 if (!isSVGFilterElement(*filter)) |
140 return nullptr; | 115 return nullptr; |
141 | 116 |
142 SVGFilterElement& filterElement = toSVGFilterElement(*filter); | 117 SVGFilterElement& filterElement = toSVGFilterElement(*filter); |
143 | 118 |
144 RefPtrWillBeRawPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(prev iousEffect); | 119 RefPtrWillBeRawPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(prev iousEffect); |
145 | 120 |
146 ColorSpace filterColorSpace = ColorSpaceDeviceRGB; | 121 EColorInterpolation filterColorInterpolation = colorInterpolationForElement( filterElement, CI_AUTO); |
147 bool useFilterColorSpace = getSVGElementColorSpace(&filterElement, filterCol orSpace); | |
148 | 122 |
149 for (SVGElement* element = Traversal<SVGElement>::firstChild(filterElement); element; element = Traversal<SVGElement>::nextSibling(*element)) { | 123 for (SVGElement* element = Traversal<SVGElement>::firstChild(filterElement); element; element = Traversal<SVGElement>::nextSibling(*element)) { |
150 if (!element->isFilterEffect()) | 124 if (!element->isFilterEffect()) |
151 continue; | 125 continue; |
152 | 126 |
153 SVGFilterPrimitiveStandardAttributes* effectElement = static_cast<SVGFil terPrimitiveStandardAttributes*>(element); | 127 SVGFilterPrimitiveStandardAttributes* effectElement = static_cast<SVGFil terPrimitiveStandardAttributes*>(element); |
154 | |
155 RefPtrWillBeRawPtr<FilterEffect> effect = effectElement->build(builder.g et(), parentFilter); | 128 RefPtrWillBeRawPtr<FilterEffect> effect = effectElement->build(builder.g et(), parentFilter); |
156 if (!effect) | 129 if (!effect) |
157 continue; | 130 continue; |
158 | 131 |
159 effectElement->setStandardAttributes(effect.get()); | 132 effectElement->setStandardAttributes(effect.get()); |
160 effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilter PrimitiveStandardAttributes>(effectElement, filterElement.primitiveUnits()->curr entValue()->enumValue(), parentFilter->sourceImageRect())); | 133 effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilter PrimitiveStandardAttributes>(effectElement, filterElement.primitiveUnits()->curr entValue()->enumValue(), parentFilter->sourceImageRect())); |
161 ColorSpace colorSpace = filterColorSpace; | 134 EColorInterpolation colorInterpolation = colorInterpolationForElement(*e ffectElement, filterColorInterpolation); |
162 if (useFilterColorSpace || getSVGElementColorSpace(effectElement, colorS pace)) | 135 effect->setOperatingColorSpace(colorInterpolation == CI_LINEARRGB ? Colo rSpaceLinearRGB : ColorSpaceDeviceRGB); |
163 effect->setOperatingColorSpace(colorSpace); | |
164 builder->add(AtomicString(effectElement->result()->currentValue()->value ()), effect); | 136 builder->add(AtomicString(effectElement->result()->currentValue()->value ()), effect); |
165 } | 137 } |
166 return builder->lastEffect(); | 138 return builder->lastEffect(); |
167 } | 139 } |
168 | 140 |
169 } // namespace blink | 141 } // namespace blink |
OLD | NEW |