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