| 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 |