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) |
| 54 { |
| 55 AffineTransform ctm = getCTM(AllowStyleUpdate); |
| 56 |
| 57 if (target && target->isSVGGraphicsElement()) { |
| 58 AffineTransform targetCTM = toSVGGraphicsElement(target)->getCTM(AllowSt
yleUpdate); |
| 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(SVGGraphicsElement* element, SVGElement::CTMSc
ope 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
? element->nearestViewportElement() : 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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 | 188 |
150 if (attrName == SVGNames::transformAttr) { | 189 if (attrName == SVGNames::transformAttr) { |
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 |
| 198 static bool isViewportElement(Node* node) |
| 199 { |
| 200 return (node->hasTagName(SVGNames::svgTag) |
| 201 || node->hasTagName(SVGNames::symbolTag) |
| 202 || node->hasTagName(SVGNames::foreignObjectTag) |
| 203 || node->hasTagName(SVGNames::imageTag)); |
| 204 } |
| 205 |
159 SVGElement* SVGGraphicsElement::nearestViewportElement() const | 206 SVGElement* SVGGraphicsElement::nearestViewportElement() const |
160 { | 207 { |
161 return SVGTransformable::nearestViewportElement(this); | 208 for (Element* current = parentOrShadowHostElement(); current; current = curr
ent->parentOrShadowHostElement()) { |
| 209 if (isViewportElement(current)) |
| 210 return toSVGElement(current); |
| 211 } |
| 212 |
| 213 return 0; |
162 } | 214 } |
163 | 215 |
164 SVGElement* SVGGraphicsElement::farthestViewportElement() const | 216 SVGElement* SVGGraphicsElement::farthestViewportElement() const |
165 { | 217 { |
166 return SVGTransformable::farthestViewportElement(this); | 218 SVGElement* farthest = 0; |
| 219 for (Element* current = parentOrShadowHostElement(); current; current = curr
ent->parentOrShadowHostElement()) { |
| 220 if (isViewportElement(current)) |
| 221 farthest = toSVGElement(current); |
| 222 } |
| 223 return farthest; |
167 } | 224 } |
168 | 225 |
169 SVGRect SVGGraphicsElement::getBBox() | 226 SVGRect SVGGraphicsElement::getBBox() |
170 { | 227 { |
171 document().updateLayoutIgnorePendingStylesheets(); | 228 document().updateLayoutIgnorePendingStylesheets(); |
172 | 229 |
173 // FIXME: Eventually we should support getBBox for detached elements. | 230 // FIXME: Eventually we should support getBBox for detached elements. |
174 if (!renderer()) | 231 if (!renderer()) |
175 return SVGRect(); | 232 return SVGRect(); |
176 | 233 |
(...skipping 18 matching lines...) Expand all Loading... |
195 } | 252 } |
196 | 253 |
197 void SVGGraphicsElement::toClipPath(Path& path) | 254 void SVGGraphicsElement::toClipPath(Path& path) |
198 { | 255 { |
199 updatePathFromGraphicsElement(this, path); | 256 updatePathFromGraphicsElement(this, path); |
200 // FIXME: How do we know the element has done a layout? | 257 // FIXME: How do we know the element has done a layout? |
201 path.transform(animatedLocalTransform()); | 258 path.transform(animatedLocalTransform()); |
202 } | 259 } |
203 | 260 |
204 } | 261 } |
OLD | NEW |