Chromium Code Reviews| 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 |