| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> |
| 3 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 3 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 4 * Copyright 2014 The Chromium Authors. All rights reserved. | 4 * Copyright 2014 The Chromium Authors. All rights reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 void LayoutSVGResourcePattern::removeAllClientsFromCache( | 54 void LayoutSVGResourcePattern::removeAllClientsFromCache( |
| 55 bool markForInvalidation) { | 55 bool markForInvalidation) { |
| 56 m_patternMap.clear(); | 56 m_patternMap.clear(); |
| 57 m_shouldCollectPatternAttributes = true; | 57 m_shouldCollectPatternAttributes = true; |
| 58 markAllClientsForInvalidation(markForInvalidation ? PaintInvalidation | 58 markAllClientsForInvalidation(markForInvalidation ? PaintInvalidation |
| 59 : ParentOnlyInvalidation); | 59 : ParentOnlyInvalidation); |
| 60 } | 60 } |
| 61 | 61 |
| 62 void LayoutSVGResourcePattern::removeClientFromCache(LayoutObject* client, | 62 void LayoutSVGResourcePattern::removeClientFromCache(LayoutObject* client, |
| 63 bool markForInvalidation) { | 63 bool markForInvalidation) { |
| 64 ASSERT(client); | 64 DCHECK(client); |
| 65 m_patternMap.erase(client); | 65 m_patternMap.erase(client); |
| 66 markClientForInvalidation( | 66 markClientForInvalidation( |
| 67 client, markForInvalidation ? PaintInvalidation : ParentOnlyInvalidation); | 67 client, markForInvalidation ? PaintInvalidation : ParentOnlyInvalidation); |
| 68 } | 68 } |
| 69 | 69 |
| 70 PatternData* LayoutSVGResourcePattern::patternForLayoutObject( | 70 PatternData* LayoutSVGResourcePattern::patternForLayoutObject( |
| 71 const LayoutObject& object) { | 71 const LayoutObject& object) { |
| 72 ASSERT(!m_shouldCollectPatternAttributes); | 72 DCHECK(!m_shouldCollectPatternAttributes); |
| 73 | 73 |
| 74 // FIXME: the double hash lookup is needed to guard against paint-time | 74 // FIXME: the double hash lookup is needed to guard against paint-time |
| 75 // invalidation (painting animated images may trigger layout invals which | 75 // invalidation (painting animated images may trigger layout invals which |
| 76 // delete our map entry). Hopefully that will be addressed at some point, and | 76 // delete our map entry). Hopefully that will be addressed at some point, and |
| 77 // then we can optimize the lookup. | 77 // then we can optimize the lookup. |
| 78 if (PatternData* currentData = m_patternMap.at(&object)) | 78 if (PatternData* currentData = m_patternMap.at(&object)) |
| 79 return currentData; | 79 return currentData; |
| 80 | 80 |
| 81 return m_patternMap.set(&object, buildPatternData(object)) | 81 return m_patternMap.set(&object, buildPatternData(object)) |
| 82 .storedValue->value.get(); | 82 .storedValue->value.get(); |
| 83 } | 83 } |
| 84 | 84 |
| 85 std::unique_ptr<PatternData> LayoutSVGResourcePattern::buildPatternData( | 85 std::unique_ptr<PatternData> LayoutSVGResourcePattern::buildPatternData( |
| 86 const LayoutObject& object) { | 86 const LayoutObject& object) { |
| 87 // If we couldn't determine the pattern content element root, stop here. | 87 // If we couldn't determine the pattern content element root, stop here. |
| 88 const PatternAttributes& attributes = this->attributes(); | 88 const PatternAttributes& attributes = this->attributes(); |
| 89 if (!attributes.patternContentElement()) | 89 if (!attributes.patternContentElement()) |
| 90 return nullptr; | 90 return nullptr; |
| 91 | 91 |
| 92 // An empty viewBox disables layout. | 92 // An empty viewBox disables layout. |
| 93 if (attributes.hasViewBox() && attributes.viewBox().isEmpty()) | 93 if (attributes.hasViewBox() && attributes.viewBox().isEmpty()) |
| 94 return nullptr; | 94 return nullptr; |
| 95 | 95 |
| 96 ASSERT(element()); | 96 DCHECK(element()); |
| 97 // Compute tile metrics. | 97 // Compute tile metrics. |
| 98 FloatRect clientBoundingBox = object.objectBoundingBox(); | 98 FloatRect clientBoundingBox = object.objectBoundingBox(); |
| 99 FloatRect tileBounds = SVGLengthContext::resolveRectangle( | 99 FloatRect tileBounds = SVGLengthContext::resolveRectangle( |
| 100 element(), attributes.patternUnits(), clientBoundingBox, *attributes.x(), | 100 element(), attributes.patternUnits(), clientBoundingBox, *attributes.x(), |
| 101 *attributes.y(), *attributes.width(), *attributes.height()); | 101 *attributes.y(), *attributes.width(), *attributes.height()); |
| 102 if (tileBounds.isEmpty()) | 102 if (tileBounds.isEmpty()) |
| 103 return nullptr; | 103 return nullptr; |
| 104 | 104 |
| 105 AffineTransform tileTransform; | 105 AffineTransform tileTransform; |
| 106 if (attributes.hasViewBox()) { | 106 if (attributes.hasViewBox()) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 | 159 |
| 160 PatternData* patternData = patternForLayoutObject(object); | 160 PatternData* patternData = patternForLayoutObject(object); |
| 161 if (!patternData || !patternData->pattern) | 161 if (!patternData || !patternData->pattern) |
| 162 return SVGPaintServer::invalid(); | 162 return SVGPaintServer::invalid(); |
| 163 | 163 |
| 164 return SVGPaintServer(patternData->pattern, patternData->transform); | 164 return SVGPaintServer(patternData->pattern, patternData->transform); |
| 165 } | 165 } |
| 166 | 166 |
| 167 const LayoutSVGResourceContainer* | 167 const LayoutSVGResourceContainer* |
| 168 LayoutSVGResourcePattern::resolveContentElement() const { | 168 LayoutSVGResourcePattern::resolveContentElement() const { |
| 169 ASSERT(attributes().patternContentElement()); | 169 DCHECK(attributes().patternContentElement()); |
| 170 LayoutSVGResourceContainer* expectedLayoutObject = | 170 LayoutSVGResourceContainer* expectedLayoutObject = |
| 171 toLayoutSVGResourceContainer( | 171 toLayoutSVGResourceContainer( |
| 172 attributes().patternContentElement()->layoutObject()); | 172 attributes().patternContentElement()->layoutObject()); |
| 173 // No content inheritance - avoid walking the inheritance chain. | 173 // No content inheritance - avoid walking the inheritance chain. |
| 174 if (this == expectedLayoutObject) | 174 if (this == expectedLayoutObject) |
| 175 return this; | 175 return this; |
| 176 // Walk the inheritance chain on the LayoutObject-side. If we reach the | 176 // Walk the inheritance chain on the LayoutObject-side. If we reach the |
| 177 // expected LayoutObject, all is fine. If we don't, there's a cycle that | 177 // expected LayoutObject, all is fine. If we don't, there's a cycle that |
| 178 // the cycle resolver did break, and the resource will be content-less. | 178 // the cycle resolver did break, and the resource will be content-less. |
| 179 const LayoutSVGResourceContainer* contentLayoutObject = this; | 179 const LayoutSVGResourceContainer* contentLayoutObject = this; |
| 180 while (SVGResources* resources = | 180 while (SVGResources* resources = |
| 181 SVGResourcesCache::cachedResourcesForLayoutObject( | 181 SVGResourcesCache::cachedResourcesForLayoutObject( |
| 182 contentLayoutObject)) { | 182 contentLayoutObject)) { |
| 183 LayoutSVGResourceContainer* linkedResource = resources->linkedResource(); | 183 LayoutSVGResourceContainer* linkedResource = resources->linkedResource(); |
| 184 if (!linkedResource) | 184 if (!linkedResource) |
| 185 break; | 185 break; |
| 186 if (linkedResource == expectedLayoutObject) | 186 if (linkedResource == expectedLayoutObject) |
| 187 return expectedLayoutObject; | 187 return expectedLayoutObject; |
| 188 contentLayoutObject = linkedResource; | 188 contentLayoutObject = linkedResource; |
| 189 } | 189 } |
| 190 // There was a cycle, just use this resource as the "content resource" even | 190 // There was a cycle, just use this resource as the "content resource" even |
| 191 // though it will be empty (have no children). | 191 // though it will be empty (have no children). |
| 192 return this; | 192 return this; |
| 193 } | 193 } |
| 194 | 194 |
| 195 sk_sp<PaintRecord> LayoutSVGResourcePattern::asPaintRecord( | 195 sk_sp<PaintRecord> LayoutSVGResourcePattern::asPaintRecord( |
| 196 const FloatRect& tileBounds, | 196 const FloatRect& tileBounds, |
| 197 const AffineTransform& tileTransform) const { | 197 const AffineTransform& tileTransform) const { |
| 198 ASSERT(!m_shouldCollectPatternAttributes); | 198 DCHECK(!m_shouldCollectPatternAttributes); |
| 199 | 199 |
| 200 AffineTransform contentTransform; | 200 AffineTransform contentTransform; |
| 201 if (attributes().patternContentUnits() == | 201 if (attributes().patternContentUnits() == |
| 202 SVGUnitTypes::kSvgUnitTypeObjectboundingbox) | 202 SVGUnitTypes::kSvgUnitTypeObjectboundingbox) |
| 203 contentTransform = tileTransform; | 203 contentTransform = tileTransform; |
| 204 | 204 |
| 205 FloatRect bounds(FloatPoint(), tileBounds.size()); | 205 FloatRect bounds(FloatPoint(), tileBounds.size()); |
| 206 PaintRecordBuilder builder(bounds); | 206 PaintRecordBuilder builder(bounds); |
| 207 | 207 |
| 208 const LayoutSVGResourceContainer* patternLayoutObject = | 208 const LayoutSVGResourceContainer* patternLayoutObject = |
| 209 resolveContentElement(); | 209 resolveContentElement(); |
| 210 ASSERT(patternLayoutObject && !patternLayoutObject->needsLayout()); | 210 DCHECK(patternLayoutObject); |
| 211 DCHECK(!patternLayoutObject->needsLayout()); |
| 211 | 212 |
| 212 SubtreeContentTransformScope contentTransformScope(contentTransform); | 213 SubtreeContentTransformScope contentTransformScope(contentTransform); |
| 213 | 214 |
| 214 { | 215 { |
| 215 TransformRecorder transformRecorder(builder.context(), *patternLayoutObject, | 216 TransformRecorder transformRecorder(builder.context(), *patternLayoutObject, |
| 216 tileTransform); | 217 tileTransform); |
| 217 for (LayoutObject* child = patternLayoutObject->firstChild(); child; | 218 for (LayoutObject* child = patternLayoutObject->firstChild(); child; |
| 218 child = child->nextSibling()) | 219 child = child->nextSibling()) |
| 219 SVGPaintContext::paintResourceSubtree(builder.context(), child); | 220 SVGPaintContext::paintResourceSubtree(builder.context(), child); |
| 220 } | 221 } |
| 221 | 222 |
| 222 return builder.endRecording(); | 223 return builder.endRecording(); |
| 223 } | 224 } |
| 224 | 225 |
| 225 } // namespace blink | 226 } // namespace blink |
| OLD | NEW |