OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 25 matching lines...) Expand all Loading... |
36 { | 36 { |
37 } | 37 } |
38 | 38 |
39 void SVGResourcesCache::addResourcesFromLayoutObject(LayoutObject* object, const
ComputedStyle& style) | 39 void SVGResourcesCache::addResourcesFromLayoutObject(LayoutObject* object, const
ComputedStyle& style) |
40 { | 40 { |
41 ASSERT(object); | 41 ASSERT(object); |
42 ASSERT(!m_cache.contains(object)); | 42 ASSERT(!m_cache.contains(object)); |
43 | 43 |
44 const SVGComputedStyle& svgStyle = style.svgStyle(); | 44 const SVGComputedStyle& svgStyle = style.svgStyle(); |
45 | 45 |
46 // Build a list of all resources associated with the passed LayoutObject | 46 // Build a list of all resources associated with the passed LayoutObject. |
47 OwnPtr<SVGResources> newResources = SVGResources::buildResources(object, svg
Style); | 47 OwnPtr<SVGResources> newResources = SVGResources::buildResources(object, svg
Style); |
48 if (!newResources) | 48 if (!newResources) |
49 return; | 49 return; |
50 | 50 |
51 // Put object in cache. | 51 // Put object in cache. |
52 SVGResources* resources = m_cache.set(object, newResources.release()).stored
Value->value.get(); | 52 SVGResources* resources = m_cache.set(object, newResources.release()).stored
Value->value.get(); |
53 | 53 |
54 // Run cycle-detection _afterwards_, so self-references can be caught as wel
l. | 54 // Run cycle-detection _afterwards_, so self-references can be caught as wel
l. |
55 SVGResourcesCycleSolver solver(object, resources); | 55 SVGResourcesCycleSolver solver(object, resources); |
56 solver.resolveCycles(); | 56 solver.resolveCycles(); |
57 | 57 |
58 // Walk resources and register the layout object at each resources. | 58 // Walk resources and register the layout object as a client of each resourc
e. |
59 HashSet<LayoutSVGResourceContainer*> resourceSet; | 59 HashSet<LayoutSVGResourceContainer*> resourceSet; |
60 resources->buildSetOfResources(resourceSet); | 60 resources->buildSetOfResources(resourceSet); |
61 | 61 |
62 for (auto* resourceContainer : resourceSet) | 62 for (auto* resourceContainer : resourceSet) |
63 resourceContainer->addClient(object); | 63 resourceContainer->addClient(object); |
64 } | 64 } |
65 | 65 |
66 void SVGResourcesCache::removeResourcesFromLayoutObject(LayoutObject* object) | 66 void SVGResourcesCache::removeResourcesFromLayoutObject(LayoutObject* object) |
67 { | 67 { |
68 OwnPtr<SVGResources> resources = m_cache.take(object); | 68 OwnPtr<SVGResources> resources = m_cache.take(object); |
69 if (!resources) | 69 if (!resources) |
70 return; | 70 return; |
71 | 71 |
72 // Walk resources and register the layout object at each resources. | 72 // Walk resources and unregister the layout object as a client of each resou
rce. |
73 HashSet<LayoutSVGResourceContainer*> resourceSet; | 73 HashSet<LayoutSVGResourceContainer*> resourceSet; |
74 resources->buildSetOfResources(resourceSet); | 74 resources->buildSetOfResources(resourceSet); |
75 | 75 |
76 for (auto* resourceContainer : resourceSet) | 76 for (auto* resourceContainer : resourceSet) |
77 resourceContainer->removeClient(object); | 77 resourceContainer->removeClient(object); |
78 } | 78 } |
79 | 79 |
80 static inline SVGResourcesCache* resourcesCacheFromLayoutObject(const LayoutObje
ct* layoutObject) | 80 static inline SVGResourcesCache& resourcesCache(Document& document) |
81 { | 81 { |
82 Document& document = layoutObject->document(); | 82 return document.accessSVGExtensions().resourcesCache(); |
83 | |
84 SVGDocumentExtensions& extensions = document.accessSVGExtensions(); | |
85 SVGResourcesCache* cache = extensions.resourcesCache(); | |
86 ASSERT(cache); | |
87 | |
88 return cache; | |
89 } | 83 } |
90 | 84 |
91 SVGResources* SVGResourcesCache::cachedResourcesForLayoutObject(const LayoutObje
ct* layoutObject) | 85 SVGResources* SVGResourcesCache::cachedResourcesForLayoutObject(const LayoutObje
ct* layoutObject) |
92 { | 86 { |
93 ASSERT(layoutObject); | 87 ASSERT(layoutObject); |
94 return resourcesCacheFromLayoutObject(layoutObject)->m_cache.get(layoutObjec
t); | 88 return resourcesCache(layoutObject->document()).m_cache.get(layoutObject); |
95 } | 89 } |
96 | 90 |
97 void SVGResourcesCache::clientLayoutChanged(LayoutObject* object) | 91 void SVGResourcesCache::clientLayoutChanged(LayoutObject* object) |
98 { | 92 { |
99 SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObject(
object); | 93 SVGResources* resources = cachedResourcesForLayoutObject(object); |
100 if (!resources) | 94 if (!resources) |
101 return; | 95 return; |
102 | 96 |
103 // Invalidate the resources if either the LayoutObject itself changed, | 97 // Invalidate the resources if either the LayoutObject itself changed, |
104 // or we have filter resources, which could depend on the layout of children
. | 98 // or we have filter resources, which could depend on the layout of children
. |
105 if (object->selfNeedsLayout() || resources->filter()) | 99 if (object->selfNeedsLayout() || resources->filter()) |
106 resources->removeClientFromCache(object); | 100 resources->removeClientFromCache(object); |
107 } | 101 } |
108 | 102 |
109 static inline bool layoutObjectCanHaveResources(LayoutObject* layoutObject) | 103 static inline bool layoutObjectCanHaveResources(LayoutObject* layoutObject) |
110 { | 104 { |
111 ASSERT(layoutObject); | 105 ASSERT(layoutObject); |
112 return layoutObject->node() && layoutObject->node()->isSVGElement() && !layo
utObject->isSVGInlineText(); | 106 return layoutObject->node() && layoutObject->node()->isSVGElement() && !layo
utObject->isSVGInlineText(); |
113 } | 107 } |
114 | 108 |
115 void SVGResourcesCache::clientStyleChanged(LayoutObject* layoutObject, StyleDiff
erence diff, const ComputedStyle& newStyle) | 109 void SVGResourcesCache::clientStyleChanged(LayoutObject* layoutObject, StyleDiff
erence diff, const ComputedStyle& newStyle) |
116 { | 110 { |
117 ASSERT(layoutObject); | 111 ASSERT(layoutObject); |
118 ASSERT(layoutObject->node()); | 112 ASSERT(layoutObject->node()); |
119 ASSERT(layoutObject->node()->isSVGElement()); | 113 ASSERT(layoutObject->node()->isSVGElement()); |
120 | 114 |
121 if (!diff.hasDifference() || !layoutObject->parent()) | 115 if (!diff.hasDifference() || !layoutObject->parent()) |
122 return; | 116 return; |
123 | 117 |
124 // In this case the proper SVGFE*Element will decide whether the modified CS
S properties require a relayout or paintInvalidation. | 118 // In this case the proper SVGFE*Element will decide whether the modified CS
S properties require |
| 119 // a relayout or paintInvalidation. |
125 if (layoutObject->isSVGResourceFilterPrimitive() && !diff.needsLayout()) | 120 if (layoutObject->isSVGResourceFilterPrimitive() && !diff.needsLayout()) |
126 return; | 121 return; |
127 | 122 |
128 // Dynamic changes of CSS properties like 'clip-path' may require us to reco
mpute the associated resources for a layoutObject. | 123 // Dynamic changes of CSS properties like 'clip-path' may require us to reco
mpute the associated |
129 // FIXME: Avoid passing in a useless StyleDifference, but instead compare ol
dStyle/newStyle to see which resources changed | 124 // resources for a LayoutObject. |
130 // to be able to selectively rebuild individual resources, instead of all of
them. | 125 // TODO(fs): Avoid passing in a useless StyleDifference, but instead compare
oldStyle/newStyle |
| 126 // to see which resources changed to be able to selectively rebuild individu
al resources, |
| 127 // instead of all of them. |
131 if (layoutObjectCanHaveResources(layoutObject)) { | 128 if (layoutObjectCanHaveResources(layoutObject)) { |
132 SVGResourcesCache* cache = resourcesCacheFromLayoutObject(layoutObject); | 129 SVGResourcesCache& cache = resourcesCache(layoutObject->document()); |
133 cache->removeResourcesFromLayoutObject(layoutObject); | 130 cache.removeResourcesFromLayoutObject(layoutObject); |
134 cache->addResourcesFromLayoutObject(layoutObject, newStyle); | 131 cache.addResourcesFromLayoutObject(layoutObject, newStyle); |
135 } | 132 } |
136 | 133 |
137 LayoutSVGResourceContainer::markForLayoutAndParentResourceInvalidation(layou
tObject, false); | 134 LayoutSVGResourceContainer::markForLayoutAndParentResourceInvalidation(layou
tObject, false); |
138 } | 135 } |
139 | 136 |
140 void SVGResourcesCache::clientWasAddedToTree(LayoutObject* layoutObject, const C
omputedStyle& newStyle) | 137 void SVGResourcesCache::clientWasAddedToTree(LayoutObject* layoutObject, const C
omputedStyle& newStyle) |
141 { | 138 { |
142 if (!layoutObject->node()) | 139 if (!layoutObject->node()) |
143 return; | 140 return; |
144 LayoutSVGResourceContainer::markForLayoutAndParentResourceInvalidation(layou
tObject, false); | 141 LayoutSVGResourceContainer::markForLayoutAndParentResourceInvalidation(layou
tObject, false); |
145 | 142 |
146 if (!layoutObjectCanHaveResources(layoutObject)) | 143 if (!layoutObjectCanHaveResources(layoutObject)) |
147 return; | 144 return; |
148 SVGResourcesCache* cache = resourcesCacheFromLayoutObject(layoutObject); | 145 SVGResourcesCache& cache = resourcesCache(layoutObject->document()); |
149 cache->addResourcesFromLayoutObject(layoutObject, newStyle); | 146 cache.addResourcesFromLayoutObject(layoutObject, newStyle); |
150 } | 147 } |
151 | 148 |
152 void SVGResourcesCache::clientWillBeRemovedFromTree(LayoutObject* layoutObject) | 149 void SVGResourcesCache::clientWillBeRemovedFromTree(LayoutObject* layoutObject) |
153 { | 150 { |
154 if (!layoutObject->node()) | 151 if (!layoutObject->node()) |
155 return; | 152 return; |
156 LayoutSVGResourceContainer::markForLayoutAndParentResourceInvalidation(layou
tObject, false); | 153 LayoutSVGResourceContainer::markForLayoutAndParentResourceInvalidation(layou
tObject, false); |
157 | 154 |
158 if (!layoutObjectCanHaveResources(layoutObject)) | 155 if (!layoutObjectCanHaveResources(layoutObject)) |
159 return; | 156 return; |
160 SVGResourcesCache* cache = resourcesCacheFromLayoutObject(layoutObject); | 157 SVGResourcesCache& cache = resourcesCache(layoutObject->document()); |
161 cache->removeResourcesFromLayoutObject(layoutObject); | 158 cache.removeResourcesFromLayoutObject(layoutObject); |
162 } | 159 } |
163 | 160 |
164 void SVGResourcesCache::clientDestroyed(LayoutObject* layoutObject) | 161 void SVGResourcesCache::clientDestroyed(LayoutObject* layoutObject) |
165 { | 162 { |
166 ASSERT(layoutObject); | 163 ASSERT(layoutObject); |
167 | 164 |
168 SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObject(
layoutObject); | 165 SVGResources* resources = cachedResourcesForLayoutObject(layoutObject); |
169 if (resources) | 166 if (resources) |
170 resources->removeClientFromCache(layoutObject); | 167 resources->removeClientFromCache(layoutObject); |
171 | 168 SVGResourcesCache& cache = resourcesCache(layoutObject->document()); |
172 SVGResourcesCache* cache = resourcesCacheFromLayoutObject(layoutObject); | 169 cache.removeResourcesFromLayoutObject(layoutObject); |
173 cache->removeResourcesFromLayoutObject(layoutObject); | |
174 } | 170 } |
175 | 171 |
176 void SVGResourcesCache::resourceDestroyed(LayoutSVGResourceContainer* resource) | 172 void SVGResourcesCache::resourceDestroyed(LayoutSVGResourceContainer* resource) |
177 { | 173 { |
178 ASSERT(resource); | 174 ASSERT(resource); |
179 SVGResourcesCache* cache = resourcesCacheFromLayoutObject(resource); | 175 SVGResourcesCache& cache = resourcesCache(resource->document()); |
180 | 176 |
181 // The resource itself may have clients, that need to be notified. | 177 // The resource itself may have clients, that need to be notified. |
182 cache->removeResourcesFromLayoutObject(resource); | 178 cache.removeResourcesFromLayoutObject(resource); |
183 | 179 |
184 for (auto& objectResources : cache->m_cache) { | 180 for (auto& objectResources : cache.m_cache) { |
185 objectResources.value->resourceDestroyed(resource); | 181 objectResources.value->resourceDestroyed(resource); |
186 | 182 |
187 // Mark users of destroyed resources as pending resolution based on the
id of the old resource. | 183 // Mark users of destroyed resources as pending resolution based on the
id of the old resource. |
188 Element* resourceElement = resource->element(); | 184 Element* resourceElement = resource->element(); |
189 Element* clientElement = toElement(objectResources.key->node()); | 185 Element* clientElement = toElement(objectResources.key->node()); |
190 SVGDocumentExtensions& extensions = clientElement->document().accessSVGE
xtensions(); | 186 SVGDocumentExtensions& extensions = clientElement->document().accessSVGE
xtensions(); |
191 | 187 |
192 extensions.addPendingResource(resourceElement->fastGetAttribute(HTMLName
s::idAttr), clientElement); | 188 extensions.addPendingResource(resourceElement->fastGetAttribute(HTMLName
s::idAttr), clientElement); |
193 } | 189 } |
194 } | 190 } |
195 | 191 |
196 } | 192 } |
OLD | NEW |