OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> |
3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 SVGGraphicsElement::SVGGraphicsElement(const QualifiedName& tagName, Document& d
ocument, ConstructionType constructionType) | 43 SVGGraphicsElement::SVGGraphicsElement(const QualifiedName& tagName, Document& d
ocument, ConstructionType constructionType) |
44 : SVGElement(tagName, document, constructionType) | 44 : SVGElement(tagName, document, constructionType) |
45 { | 45 { |
46 registerAnimatedPropertiesForSVGGraphicsElement(); | 46 registerAnimatedPropertiesForSVGGraphicsElement(); |
47 } | 47 } |
48 | 48 |
49 SVGGraphicsElement::~SVGGraphicsElement() | 49 SVGGraphicsElement::~SVGGraphicsElement() |
50 { | 50 { |
51 } | 51 } |
52 | 52 |
| 53 AffineTransform SVGGraphicsElement::getTransformToElement(SVGElement* target, Ex
ceptionState& es, StyleUpdateStrategy styleUpdateStrategy) |
| 54 { |
| 55 AffineTransform ctm = getCTM(styleUpdateStrategy); |
| 56 |
| 57 if (target && target->isSVGGraphicsElement()) { |
| 58 AffineTransform targetCTM = toSVGGraphicsElement(target)->getCTM(styleUp
dateStrategy); |
| 59 if (!targetCTM.isInvertible()) { |
| 60 es.throwUninformativeAndGenericDOMException(InvalidStateError); |
| 61 return ctm; |
| 62 } |
| 63 ctm = targetCTM.inverse() * ctm; |
| 64 } |
| 65 |
| 66 return ctm; |
| 67 } |
| 68 |
| 69 static AffineTransform computeCTM(SVGElement* element, SVGElement::CTMScope mode
, SVGGraphicsElement::StyleUpdateStrategy styleUpdateStrategy) |
| 70 { |
| 71 ASSERT(element); |
| 72 if (styleUpdateStrategy == SVGGraphicsElement::AllowStyleUpdate) |
| 73 element->document().updateLayoutIgnorePendingStylesheets(); |
| 74 |
| 75 AffineTransform ctm; |
| 76 |
| 77 SVGElement* stopAtElement = mode == SVGGraphicsElement::NearestViewportScope
? SVGGraphicsElement::nearestViewportElement(element) : 0; |
| 78 for (Element* currentElement = element; currentElement; currentElement = cur
rentElement->parentOrShadowHostElement()) { |
| 79 if (!currentElement->isSVGElement()) |
| 80 break; |
| 81 |
| 82 ctm = toSVGElement(currentElement)->localCoordinateSpaceTransform(mode).
multiply(ctm); |
| 83 |
| 84 // For getCTM() computation, stop at the nearest viewport element |
| 85 if (currentElement == stopAtElement) |
| 86 break; |
| 87 } |
| 88 |
| 89 return ctm; |
| 90 } |
| 91 |
53 AffineTransform SVGGraphicsElement::getCTM(StyleUpdateStrategy styleUpdateStrate
gy) | 92 AffineTransform SVGGraphicsElement::getCTM(StyleUpdateStrategy styleUpdateStrate
gy) |
54 { | 93 { |
55 return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, st
yleUpdateStrategy); | 94 return computeCTM(this, NearestViewportScope, styleUpdateStrategy); |
56 } | 95 } |
57 | 96 |
58 AffineTransform SVGGraphicsElement::getScreenCTM(StyleUpdateStrategy styleUpdate
Strategy) | 97 AffineTransform SVGGraphicsElement::getScreenCTM(StyleUpdateStrategy styleUpdate
Strategy) |
59 { | 98 { |
60 return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdate
Strategy); | 99 return computeCTM(this, ScreenScope, styleUpdateStrategy); |
61 } | 100 } |
62 | 101 |
63 AffineTransform SVGGraphicsElement::animatedLocalTransform() const | 102 AffineTransform SVGGraphicsElement::animatedLocalTransform() const |
64 { | 103 { |
65 AffineTransform matrix; | 104 AffineTransform matrix; |
66 RenderStyle* style = renderer() ? renderer()->style() : 0; | 105 RenderStyle* style = renderer() ? renderer()->style() : 0; |
67 | 106 |
68 // If CSS property was set, use that, otherwise fallback to attribute (if se
t). | 107 // If CSS property was set, use that, otherwise fallback to attribute (if se
t). |
69 if (style && style->hasTransform()) { | 108 if (style && style->hasTransform()) { |
70 // Note: objectBoundingBox is an emptyRect for elements like pattern or
clipPath. | 109 // Note: objectBoundingBox is an emptyRect for elements like pattern or
clipPath. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 object->setNeedsTransformUpdate(); | 190 object->setNeedsTransformUpdate(); |
152 RenderSVGResource::markForLayoutAndParentResourceInvalidation(object); | 191 RenderSVGResource::markForLayoutAndParentResourceInvalidation(object); |
153 return; | 192 return; |
154 } | 193 } |
155 | 194 |
156 ASSERT_NOT_REACHED(); | 195 ASSERT_NOT_REACHED(); |
157 } | 196 } |
158 | 197 |
159 SVGElement* SVGGraphicsElement::nearestViewportElement() const | 198 SVGElement* SVGGraphicsElement::nearestViewportElement() const |
160 { | 199 { |
161 return SVGTransformable::nearestViewportElement(this); | 200 return nearestViewportElement(this); |
| 201 } |
| 202 |
| 203 static bool isViewportElement(Node* node) |
| 204 { |
| 205 return (node->hasTagName(SVGNames::svgTag) |
| 206 || node->hasTagName(SVGNames::symbolTag) |
| 207 || node->hasTagName(SVGNames::foreignObjectTag) |
| 208 || node->hasTagName(SVGNames::imageTag)); |
162 } | 209 } |
163 | 210 |
164 SVGElement* SVGGraphicsElement::farthestViewportElement() const | 211 SVGElement* SVGGraphicsElement::farthestViewportElement() const |
165 { | 212 { |
166 return SVGTransformable::farthestViewportElement(this); | 213 SVGElement* farthest = 0; |
| 214 for (Element* current = parentOrShadowHostElement(); current; current = curr
ent->parentOrShadowHostElement()) { |
| 215 if (isViewportElement(current)) |
| 216 farthest = toSVGElement(current); |
| 217 } |
| 218 return farthest; |
| 219 } |
| 220 |
| 221 SVGElement* SVGGraphicsElement::nearestViewportElement(const SVGElement* element
) |
| 222 { |
| 223 ASSERT(element); |
| 224 for (Element* current = element->parentOrShadowHostElement(); current; curre
nt = current->parentOrShadowHostElement()) { |
| 225 if (isViewportElement(current)) |
| 226 return toSVGElement(current); |
| 227 } |
| 228 |
| 229 return 0; |
167 } | 230 } |
168 | 231 |
169 SVGRect SVGGraphicsElement::getBBox() | 232 SVGRect SVGGraphicsElement::getBBox() |
170 { | 233 { |
171 document().updateLayoutIgnorePendingStylesheets(); | 234 document().updateLayoutIgnorePendingStylesheets(); |
172 | 235 |
173 // FIXME: Eventually we should support getBBox for detached elements. | 236 // FIXME: Eventually we should support getBBox for detached elements. |
174 if (!renderer()) | 237 if (!renderer()) |
175 return SVGRect(); | 238 return SVGRect(); |
176 | 239 |
(...skipping 18 matching lines...) Expand all Loading... |
195 } | 258 } |
196 | 259 |
197 void SVGGraphicsElement::toClipPath(Path& path) | 260 void SVGGraphicsElement::toClipPath(Path& path) |
198 { | 261 { |
199 updatePathFromGraphicsElement(this, path); | 262 updatePathFromGraphicsElement(this, path); |
200 // FIXME: How do we know the element has done a layout? | 263 // FIXME: How do we know the element has done a layout? |
201 path.transform(animatedLocalTransform()); | 264 path.transform(animatedLocalTransform()); |
202 } | 265 } |
203 | 266 |
204 } | 267 } |
OLD | NEW |