/* Copyright (C) 2002-2003 KSVG Team This file is part of the KDE project This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "SVGRectImpl.h" #include "SVGMatrixImpl.h" #include "SVGHelperImpl.h" #include "SVGElementImpl.h" #include "SVGDocumentImpl.h" #include "SVGStylableImpl.h" #include "SVGTransformImpl.h" #include "SVGStringListImpl.h" #include "SVGSVGElementImpl.h" #include "SVGTransformListImpl.h" #include "SVGTransformableImpl.h" #include "SVGAnimatedLengthImpl.h" #include "SVGAnimatedLengthListImpl.h" #include "KSVGCanvas.h" #include "CanvasItem.h" using namespace KSVG; #include "ksvg_ecma.h" #include "ksvg_window.h" SVGHelperImpl::SVGHelperImpl() { } SVGHelperImpl::~SVGHelperImpl() { } void SVGHelperImpl::updateItem(KJS::ExecState *exec, const DOM::Node node) { // Get document SVGDocumentImpl *doc = Window::retrieveActive(exec)->doc(); // Update canvas, recursively if needed SVGShapeImpl *shape = dynamic_cast(doc->getElementFromHandle(node.handle())); if(shape && shape->item()) { shape->item()->update(UPDATE_TRANSFORM); shape->item()->draw(); shape->blit(doc->canvas()); } if(const_cast(node).hasChildNodes()) { DOM::Node iterate = node.firstChild(); for(; !iterate.isNull(); iterate = iterate.nextSibling()) updateItem(exec, iterate); } } void SVGHelperImpl::copyAttributes(SVGElementImpl *src, SVGElementImpl *dst) { TQDictIterator it(src->attributes()); for(; it.current(); ++it) { DOM::DOMString name = it.currentKey(); DOM::DOMString value = it.current()->string(); if(name != "id" && !dst->hasAttribute(name)) { dst->setAttribute(name, value); dst->setAttributeInternal(name, value); } } } void SVGHelperImpl::parseList(SVGStringListImpl *list, char seperator, const TQString &data) { // TODO : more error checking/reporting list->clear(); TQStringList substrings = TQStringList::split(seperator, data); TQStringList::ConstIterator it = substrings.begin(); TQStringList::ConstIterator end = substrings.end(); for(; it != end; ++it) { SharedString *string = new SharedString(*it); string->ref(); list->appendItem(string); } } void SVGHelperImpl::parseLengthList(SVGAnimatedLengthListImpl *list, const TQString &lengths, LengthMode mode, SVGElementImpl *object) { // get either comma or space delimited lists // TODO : more error checking/reporting TQStringList sublengths = TQStringList::split(TQRegExp("[, ]"), lengths); TQStringList::ConstIterator it = sublengths.begin(); TQStringList::ConstIterator end = sublengths.end(); SVGLengthImpl *lengthImpl = 0; for(; it != end; ++it) { lengthImpl = new SVGLengthImpl(mode, object); lengthImpl->ref(); lengthImpl->setValueAsString(*it); list->baseVal()->appendItem(lengthImpl); } } void SVGHelperImpl::parseCommaSeperatedList(SVGStringListImpl *list, const TQString &data) { parseList(list, ',', data); } void SVGHelperImpl::parseSemicolonSeperatedList(SVGStringListImpl *list, const TQString &data) { parseList(list, ';', data); } void SVGHelperImpl::parseTransformAttribute(SVGTransformListImpl *list, const TQString &transform) { // Split string for handling 1 transform statement at a time TQStringList subtransforms = TQStringList::split(')', transform); TQStringList::ConstIterator it = subtransforms.begin(); TQStringList::ConstIterator end = subtransforms.end(); for(; it != end; ++it) { TQStringList subtransform = TQStringList::split('(', (*it)); subtransform[0] = subtransform[0].stripWhiteSpace().lower(); subtransform[1] = subtransform[1].simplifyWhiteSpace(); TQRegExp reg("([-]?\\d*\\.?\\d+(?:e[-]?\\d+)?)"); int pos = 0; TQStringList params; while(pos >= 0) { pos = reg.search(subtransform[1], pos); if(pos != -1) { params += reg.cap(1); pos += reg.matchedLength(); } } if(subtransform[0].startsWith(";") || subtransform[0].startsWith(",")) subtransform[0] = subtransform[0].right(subtransform[0].length() - 1); SVGTransformImpl *t = SVGSVGElementImpl::createSVGTransform(); if(subtransform[0] == "rotate") { if(params.count() == 3) t->setRotate(params[0].toDouble(), params[1].toDouble(), params[2].toDouble()); else t->setRotate(params[0].toDouble(), 0, 0); } else if(subtransform[0] == "translate") { if(params.count() == 2) t->setTranslate(params[0].toDouble(), params[1].toDouble()); else // Spec : if only one param given, assume 2nd param to be 0 t->setTranslate(params[0].toDouble(), 0); } else if(subtransform[0] == "scale") { if(params.count() == 2) t->setScale(params[0].toDouble(), params[1].toDouble()); else // Spec : if only one param given, assume uniform scaling t->setScale(params[0].toDouble(), params[0].toDouble()); } else if(subtransform[0] == "skewx") t->setSkewX(params[0].toDouble()); else if(subtransform[0] == "skewy") t->setSkewY(params[0].toDouble()); else if(subtransform[0] == "matrix") { if(params.count() >= 6) { SVGMatrixImpl *ret = new SVGMatrixImpl(params[0].toDouble(), params[1].toDouble(), params[2].toDouble(), params[3].toDouble(), params[4].toDouble(), params[5].toDouble()); t->setMatrix(ret); } } list->appendItem(t); } } /// convert from user space to "real" pixels on rendering area TQRect SVGHelperImpl::fromUserspace(SVGElementImpl *obj, const TQRect &r) { TQRect sr; SVGLocatableImpl *locate = dynamic_cast(obj); if(locate) sr = locate->screenCTM()->qmatrix().mapRect(r); return sr; } // vim:ts=4:noet