00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "config.h"
00025 #include <wtf/Platform.h>
00026
00027 #if ENABLE(SVG)
00028 #include "SVGSVGElement.h"
00029
00030 #include "AffineTransform.h"
00031
00032 #include "css/csshelper.h"
00033
00034 #include "Document.h"
00035
00036 #include "dom/dom2_events.h"
00037
00038 #include "FloatConversion.h"
00039 #include "FloatRect.h"
00040
00041
00042
00043 #include "RenderSVGRoot.h"
00044 #include "SVGAngle.h"
00045 #include "SVGLength.h"
00046 #include "SVGNames.h"
00047 #include "SVGPreserveAspectRatio.h"
00048 #include "SVGTransform.h"
00049 #include "SVGTransformList.h"
00050
00051 #include "SVGViewSpec.h"
00052
00053
00054
00055
00056 namespace WebCore {
00057
00058
00059
00060 using namespace SVGNames;
00061
00062 SVGSVGElement::SVGSVGElement(const QualifiedName& tagName, Document* doc)
00063 : SVGStyledLocatableElement(tagName, doc)
00064 , SVGTests()
00065 , SVGLangSpace()
00066 , SVGExternalResourcesRequired()
00067 , SVGFitToViewBox()
00068 , SVGZoomAndPan()
00069 , m_x(this, LengthModeWidth)
00070 , m_y(this, LengthModeHeight)
00071 , m_width(this, LengthModeWidth)
00072 , m_height(this, LengthModeHeight)
00073 , m_useCurrentView(false)
00074
00075
00076 , m_containerSize(300, 150)
00077
00078 {
00079 setWidthBaseValue(SVGLength(this, LengthModeWidth, "100%"));
00080 setHeightBaseValue(SVGLength(this, LengthModeHeight, "100%"));
00081
00082 }
00083
00084 SVGSVGElement::~SVGSVGElement()
00085 {
00086
00087
00088
00089
00090 }
00091
00092 ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x)
00093 ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y)
00094 ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width)
00095 ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height)
00096
00097 const AtomicString& SVGSVGElement::contentScriptType() const
00098 {
00099
00100
00101
00102 ASSERT(false);
00103 return "";
00104 }
00105
00106 void SVGSVGElement::setContentScriptType(const AtomicString& type)
00107 {
00108 setAttribute(SVGNames::contentScriptTypeAttr, type);
00109 }
00110
00111 const AtomicString& SVGSVGElement::contentStyleType() const
00112 {
00113
00114
00115
00116 ASSERT(false);
00117 return "";
00118 }
00119
00120 void SVGSVGElement::setContentStyleType(const AtomicString& type)
00121 {
00122 setAttribute(SVGNames::contentStyleTypeAttr, type);
00123 }
00124
00125 FloatRect SVGSVGElement::viewport() const
00126 {
00127 double _x = 0.0;
00128 double _y = 0.0;
00129 if (!isOutermostSVG()) {
00130 _x = x().value();
00131 _y = y().value();
00132 }
00133 float w = width().value();
00134 float h = height().value();
00135 AffineTransform viewBox = viewBoxToViewTransform(w, h);
00136 double wDouble = w;
00137 double hDouble = h;
00138 viewBox.map(_x, _y, &_x, &_y);
00139 viewBox.map(w, h, &wDouble, &hDouble);
00140 return FloatRect::narrowPrecision(_x, _y, wDouble, hDouble);
00141 }
00142
00143 int SVGSVGElement::relativeWidthValue() const
00144 {
00145 SVGLength w = width();
00146 if (w.unitType() != LengthTypePercentage)
00147 return 0;
00148
00149 return static_cast<int>(w.valueAsPercentage() * m_containerSize.width());
00150 }
00151
00152 int SVGSVGElement::relativeHeightValue() const
00153 {
00154 SVGLength h = height();
00155 if (h.unitType() != LengthTypePercentage)
00156 return 0;
00157
00158 return static_cast<int>(h.valueAsPercentage() * m_containerSize.height());
00159 }
00160
00161 float SVGSVGElement::pixelUnitToMillimeterX() const
00162 {
00163
00164 return (2.54f / cssPixelsPerInch) * 10.0f;
00165 }
00166
00167 float SVGSVGElement::pixelUnitToMillimeterY() const
00168 {
00169
00170 return (2.54f / cssPixelsPerInch) * 10.0f;
00171 }
00172
00173 float SVGSVGElement::screenPixelToMillimeterX() const
00174 {
00175 return pixelUnitToMillimeterX();
00176 }
00177
00178 float SVGSVGElement::screenPixelToMillimeterY() const
00179 {
00180 return pixelUnitToMillimeterY();
00181 }
00182
00183 bool SVGSVGElement::useCurrentView() const
00184 {
00185 return m_useCurrentView;
00186 }
00187
00188 void SVGSVGElement::setUseCurrentView(bool currentView)
00189 {
00190 m_useCurrentView = currentView;
00191 }
00192
00193 SVGViewSpec* SVGSVGElement::currentView() const
00194 {
00195 if (!m_viewSpec)
00196 m_viewSpec.set(new SVGViewSpec(this));
00197
00198 return m_viewSpec.get();
00199 }
00200
00201 float SVGSVGElement::currentScale() const
00202 {
00203
00204
00205 return 1.0f;
00206 }
00207
00208 void SVGSVGElement::setCurrentScale(float scale)
00209 {
00210
00211
00212 }
00213
00214 FloatPoint SVGSVGElement::currentTranslate() const
00215 {
00216 return m_translation;
00217 }
00218
00219 void SVGSVGElement::setCurrentTranslate(const FloatPoint &translation)
00220 {
00221 m_translation = translation;
00222 if (parentNode() == document() && document()->renderer())
00223 document()->renderer()->repaint();
00224 }
00225
00226 void SVGSVGElement::addSVGWindowEventListener(const AtomicString& eventType, const Attribute* attr)
00227 {
00228
00229
00230 RefPtr<EventListener> listener = document()->accessSVGExtensions()->
00231 createSVGEventListener(attr->localName().string(), attr->value(), this);
00232
00233 }
00234
00235 void SVGSVGElement::parseMappedAttribute(MappedAttribute* attr)
00236 {
00237 kDebug() << "parse attribute: " << attr->localName() << attr->value() << endl;
00238 if (!nearestViewportElement()) {
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 }
00253 if (attr->name() == SVGNames::xAttr)
00254 setXBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
00255 else if (attr->name() == SVGNames::yAttr)
00256 setYBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
00257 else if (attr->name() == SVGNames::widthAttr) {
00258 kDebug() << "set width" << attr->value() << endl;
00259 setWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
00260 addCSSProperty(attr, CSSPropertyWidth, attr->value());
00261
00262
00263 } else if (attr->name() == SVGNames::heightAttr) {
00264 kDebug() << "set height" << attr->value() << endl;
00265 setHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
00266 addCSSProperty(attr, CSSPropertyHeight, attr->value());
00267
00268
00269 } else {
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 SVGStyledLocatableElement::parseMappedAttribute(attr);
00282 }
00283 }
00284
00285 void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
00286 {
00287 SVGStyledElement::svgAttributeChanged(attrName);
00288
00289 if (!renderer())
00290 return;
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 }
00302
00303 unsigned long SVGSVGElement::suspendRedraw(unsigned long )
00304 {
00305
00306 return 0;
00307 }
00308
00309 void SVGSVGElement::unsuspendRedraw(unsigned long , ExceptionCode& ec)
00310 {
00311
00312
00313 }
00314
00315 void SVGSVGElement::unsuspendRedrawAll()
00316 {
00317
00318 }
00319
00320 void SVGSVGElement::forceRedraw()
00321 {
00322
00323 }
00324
00325 NodeList* SVGSVGElement::getIntersectionList(const FloatRect& rect, SVGElement*)
00326 {
00327
00328 return 0;
00329 }
00330
00331 NodeList* SVGSVGElement::getEnclosureList(const FloatRect& rect, SVGElement*)
00332 {
00333
00334 return 0;
00335 }
00336
00337 bool SVGSVGElement::checkIntersection(SVGElement* element, const FloatRect& rect)
00338 {
00339
00340
00341
00342 return rect.intersects(getBBox());
00343 }
00344
00345 bool SVGSVGElement::checkEnclosure(SVGElement* element, const FloatRect& rect)
00346 {
00347
00348
00349
00350 return rect.contains(getBBox());
00351 }
00352
00353 void SVGSVGElement::deselectAll()
00354 {
00355
00356 }
00357
00358 float SVGSVGElement::createSVGNumber()
00359 {
00360 return 0.0f;
00361 }
00362
00363 SVGLength SVGSVGElement::createSVGLength()
00364 {
00365 return SVGLength();
00366 }
00367
00368 SVGAngle* SVGSVGElement::createSVGAngle()
00369 {
00370 return new SVGAngle();
00371 }
00372
00373 FloatPoint SVGSVGElement::createSVGPoint()
00374 {
00375 return FloatPoint();
00376 }
00377
00378 AffineTransform SVGSVGElement::createSVGMatrix()
00379 {
00380 return AffineTransform();
00381 }
00382
00383 FloatRect SVGSVGElement::createSVGRect()
00384 {
00385 return FloatRect();
00386 }
00387
00388 SVGTransform SVGSVGElement::createSVGTransform()
00389 {
00390 return SVGTransform();
00391 }
00392
00393 SVGTransform SVGSVGElement::createSVGTransformFromMatrix(const AffineTransform& matrix)
00394 {
00395 return SVGTransform(matrix);
00396 }
00397
00398 AffineTransform SVGSVGElement::getCTM() const
00399 {
00400 AffineTransform mat;
00401 if (!isOutermostSVG())
00402 mat.translate(x().value(), y().value());
00403
00404 if (attributes()->getNamedItem(SVGNames::viewBoxAttr)) {
00405 AffineTransform viewBox = viewBoxToViewTransform(width().value(), height().value());
00406 mat = viewBox * mat;
00407 }
00408
00409 return mat;
00410 }
00411
00412 AffineTransform SVGSVGElement::getScreenCTM() const
00413 {
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 ASSERT(false);
00443 return AffineTransform();
00444 }
00445
00446 RenderObject* SVGSVGElement::createRenderer(RenderArena* arena, RenderStyle*)
00447 {
00448 kDebug() << "create RenderSVGRoot from <svg> element" << endl;
00449 return new (arena) RenderSVGRoot(this);
00450
00451
00452
00453
00454 }
00455
00456 void SVGSVGElement::insertedIntoDocument()
00457 {
00458 document()->accessSVGExtensions()->addTimeContainer(this);
00459 SVGStyledLocatableElement::insertedIntoDocument();
00460 }
00461
00462 void SVGSVGElement::removedFromDocument()
00463 {
00464 document()->accessSVGExtensions()->removeTimeContainer(this);
00465 SVGStyledLocatableElement::removedFromDocument();
00466 }
00467
00468 void SVGSVGElement::pauseAnimations()
00469 {
00470
00471
00472 }
00473
00474 void SVGSVGElement::unpauseAnimations()
00475 {
00476
00477
00478 }
00479
00480 bool SVGSVGElement::animationsPaused() const
00481 {
00482
00483 ASSERT(false);
00484 return false;
00485 }
00486
00487 float SVGSVGElement::getCurrentTime() const
00488 {
00489
00490 ASSERT(false);
00491 return 0.0;
00492 }
00493
00494 void SVGSVGElement::setCurrentTime(float )
00495 {
00496
00497 }
00498
00499 bool SVGSVGElement::hasRelativeValues() const
00500 {
00501 return (x().isRelative() || width().isRelative() ||
00502 y().isRelative() || height().isRelative());
00503 }
00504
00505 bool SVGSVGElement::isOutermostSVG() const
00506 {
00507
00508 return !parentNode()->isSVGElement();
00509 }
00510
00511 AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const
00512 {
00513 FloatRect viewBoxRect;
00514 if (useCurrentView()) {
00515 if (currentView())
00516 viewBoxRect = currentView()->viewBox();
00517 } else
00518 viewBoxRect = viewBox();
00519 if (!viewBoxRect.width() || !viewBoxRect.height())
00520 return AffineTransform();
00521
00522 AffineTransform ctm = preserveAspectRatio()->getCTM(viewBoxRect.x(),
00523 viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(),
00524 0, 0, viewWidth, viewHeight);
00525
00526 if (useCurrentView() && currentView())
00527 return currentView()->transform()->concatenate().matrix() * ctm;
00528
00529 return ctm;
00530 }
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 void SVGSVGElement::willSaveToCache()
00552 {
00553
00554 }
00555
00556 void SVGSVGElement::willRestoreFromCache()
00557 {
00558
00559 }
00560
00561
00562 quint32 SVGSVGElement::id() const { return SVGNames::svgTag.id(); }
00563
00564 }
00565
00566 #endif // ENABLE(SVG)
00567
00568