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 // No layout has been performed, try to determine the property value |
77 const ComputedStyle* style = layoutObject ? layoutObject->style() : 0; | 77 // "manually" (used by external SVG files.) |
78 const SVGComputedStyle* svgStyle = style ? &style->svgStyle() : 0; | 78 if (const StylePropertySet* propertySet = element.presentationAttributeStyle
()) { |
79 EColorInterpolation eColorInterpolation = CI_AUTO; | 79 RefPtrWillBeRawPtr<CSSValue> cssValue = propertySet->getPropertyCSSValue
(CSSPropertyColorInterpolationFilters); |
80 if (svgStyle) { | 80 if (cssValue && cssValue->isPrimitiveValue()) { |
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()); | 81 const CSSPrimitiveValue& primitiveValue = *((CSSPrimitiveValue*)cssV
alue.get()); |
90 eColorInterpolation = (EColorInterpolation)primitiveValue; | 82 return static_cast<EColorInterpolation>(primitiveValue); |
91 } else { | |
92 return false; | |
93 } | 83 } |
94 } | 84 } |
95 | 85 // 'auto' is the default (per Filter Effects), but since the property is |
96 switch (eColorInterpolation) { | 86 // inherited, propagate the parent's value. |
97 case CI_AUTO: | 87 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 } | 88 } |
110 | 89 |
111 PassRefPtrWillBeRawPtr<FilterEffect> ReferenceFilterBuilder::build(Filter* paren
tFilter, LayoutObject* layoutObject, FilterEffect* previousEffect, const Referen
ceFilterOperation* filterOperation) | 90 PassRefPtrWillBeRawPtr<FilterEffect> ReferenceFilterBuilder::build(Filter* paren
tFilter, LayoutObject& layoutObject, FilterEffect* previousEffect, const Referen
ceFilterOperation& filterOperation) |
112 { | 91 { |
113 if (!layoutObject) | 92 TreeScope* treeScope = &layoutObject.node()->treeScope(); |
114 return nullptr; | |
115 | 93 |
116 TreeScope* treeScope = &layoutObject->node()->treeScope(); | 94 if (DocumentResourceReference* documentResourceRef = documentResourceReferen
ce(&filterOperation)) { |
117 | |
118 if (DocumentResourceReference* documentResourceRef = documentResourceReferen
ce(filterOperation)) { | |
119 DocumentResource* cachedSVGDocument = documentResourceRef->document(); | 95 DocumentResource* cachedSVGDocument = documentResourceRef->document(); |
120 | 96 |
121 // If we have an SVG document, this is an external reference. Otherwise | 97 // If we have an SVG document, this is an external reference. Otherwise |
122 // we look up the referenced node in the current document. | 98 // we look up the referenced node in the current document. |
123 if (cachedSVGDocument) | 99 if (cachedSVGDocument) |
124 treeScope = cachedSVGDocument->document(); | 100 treeScope = cachedSVGDocument->document(); |
125 } | 101 } |
126 | 102 |
127 if (!treeScope) | 103 if (!treeScope) |
128 return nullptr; | 104 return nullptr; |
129 | 105 |
130 Element* filter = treeScope->getElementById(filterOperation->fragment()); | 106 Element* filter = treeScope->getElementById(filterOperation.fragment()); |
131 | 107 |
132 if (!filter) { | 108 if (!filter) { |
133 // Although we did not find the referenced filter, it might exist later | 109 // Although we did not find the referenced filter, it might exist later |
134 // in the document. | 110 // in the document. |
135 treeScope->document().accessSVGExtensions().addPendingResource(filterOpe
ration->fragment(), toElement(layoutObject->node())); | 111 treeScope->document().accessSVGExtensions().addPendingResource(filterOpe
ration.fragment(), toElement(layoutObject.node())); |
136 return nullptr; | 112 return nullptr; |
137 } | 113 } |
138 | 114 |
139 if (!isSVGFilterElement(*filter)) | 115 if (!isSVGFilterElement(*filter)) |
140 return nullptr; | 116 return nullptr; |
141 | 117 |
142 SVGFilterElement& filterElement = toSVGFilterElement(*filter); | 118 SVGFilterElement& filterElement = toSVGFilterElement(*filter); |
143 | 119 |
144 RefPtrWillBeRawPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(prev
iousEffect); | 120 RefPtrWillBeRawPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(prev
iousEffect); |
145 | 121 |
146 ColorSpace filterColorSpace = ColorSpaceDeviceRGB; | 122 EColorInterpolation filterColorInterpolation = colorInterpolationForElement(
filterElement, CI_AUTO); |
147 bool useFilterColorSpace = getSVGElementColorSpace(&filterElement, filterCol
orSpace); | |
148 | 123 |
149 for (SVGElement* element = Traversal<SVGElement>::firstChild(filterElement);
element; element = Traversal<SVGElement>::nextSibling(*element)) { | 124 for (SVGElement* element = Traversal<SVGElement>::firstChild(filterElement);
element; element = Traversal<SVGElement>::nextSibling(*element)) { |
150 if (!element->isFilterEffect()) | 125 if (!element->isFilterEffect()) |
151 continue; | 126 continue; |
152 | 127 |
153 SVGFilterPrimitiveStandardAttributes* effectElement = static_cast<SVGFil
terPrimitiveStandardAttributes*>(element); | 128 SVGFilterPrimitiveStandardAttributes* effectElement = static_cast<SVGFil
terPrimitiveStandardAttributes*>(element); |
154 | |
155 RefPtrWillBeRawPtr<FilterEffect> effect = effectElement->build(builder.g
et(), parentFilter); | 129 RefPtrWillBeRawPtr<FilterEffect> effect = effectElement->build(builder.g
et(), parentFilter); |
156 if (!effect) | 130 if (!effect) |
157 continue; | 131 continue; |
158 | 132 |
159 effectElement->setStandardAttributes(effect.get()); | 133 effectElement->setStandardAttributes(effect.get()); |
160 effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilter
PrimitiveStandardAttributes>(effectElement, filterElement.primitiveUnits()->curr
entValue()->enumValue(), parentFilter->sourceImageRect())); | 134 effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilter
PrimitiveStandardAttributes>(effectElement, filterElement.primitiveUnits()->curr
entValue()->enumValue(), parentFilter->sourceImageRect())); |
161 ColorSpace colorSpace = filterColorSpace; | 135 EColorInterpolation colorInterpolation = colorInterpolationForElement(*e
ffectElement, filterColorInterpolation); |
162 if (useFilterColorSpace || getSVGElementColorSpace(effectElement, colorS
pace)) | 136 effect->setOperatingColorSpace(colorInterpolation == CI_LINEARRGB ? Colo
rSpaceLinearRGB : ColorSpaceDeviceRGB); |
163 effect->setOperatingColorSpace(colorSpace); | |
164 builder->add(AtomicString(effectElement->result()->currentValue()->value
()), effect); | 137 builder->add(AtomicString(effectElement->result()->currentValue()->value
()), effect); |
165 } | 138 } |
166 return builder->lastEffect(); | 139 return builder->lastEffect(); |
167 } | 140 } |
168 | 141 |
169 } // namespace blink | 142 } // namespace blink |
OLD | NEW |