void KoPathShape::applyViewboxTransformation(const KoXmlElement & element) { // apply viewbox transformation QRectF viewBox = loadOdfViewbox(element); if (! viewBox.isEmpty()) { // load the desired size QSizeF size; size.setWidth(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "width", QString()))); size.setHeight(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "height", QString()))); // load the desired position QPointF pos; pos.setX(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "x", QString()))); pos.setY(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "y", QString()))); // create matrix to transform original path data into desired size and position QMatrix viewMatrix; viewMatrix.translate(-viewBox.left(), -viewBox.top()); viewMatrix.scale(size.width() / viewBox.width(), size.height() / viewBox.height()); viewMatrix.translate(pos.x(), pos.y()); // transform the path data map(viewMatrix); } }
bool KoEnhancedPathShape::loadOdf( const KoXmlElement & element, KoShapeLoadingContext &context ) { reset(); KoXmlElement child; forEachElement( child, element ) { if( child.localName() == "enhanced-geometry" && child.namespaceURI() == KoXmlNS::draw ) { // load the viewbox QRectF viewBox = loadOdfViewbox( child ); if( ! viewBox.isEmpty() ) m_viewBox = viewBox; // load the modifiers QString modifiers = child.attributeNS( KoXmlNS::draw, "modifiers", "" ); if( ! modifiers.isEmpty() ) { addModifiers( modifiers ); } KoXmlElement grandChild; forEachElement( grandChild, child ) { if( grandChild.namespaceURI() != KoXmlNS::draw ) continue; if( grandChild.localName() == "equation" ) { QString name = grandChild.attributeNS( KoXmlNS::draw, "name" ); QString formula = grandChild.attributeNS( KoXmlNS::draw, "formula" ); addFormula( name, formula ); } else if( grandChild.localName() == "handle" ) { KoEnhancedPathHandle * handle = new KoEnhancedPathHandle( this ); if( handle->loadOdf( grandChild ) ) { m_enhancedHandles.append( handle ); evaluateHandles(); } else delete handle; } } // load the enhanced path data QString path = child.attributeNS( KoXmlNS::draw, "enhanced-path", "" ); #ifndef NWORKAROUND_ODF_BUGS KoOdfWorkaround::fixEnhancedPath(path, child, context); #endif if ( !path.isEmpty() ) { parsePathData( path ); } } }
bool KoConnectionShape::loadOdf(const KoXmlElement & element, KoShapeLoadingContext &context) { Q_D(KoConnectionShape); loadOdfAttributes(element, context, OdfMandatories | OdfCommonChildElements | OdfAdditionalAttributes); QString type = element.attributeNS(KoXmlNS::draw, "type", "standard"); if (type == "lines") d->connectionType = Lines; else if (type == "line") d->connectionType = Straight; else if (type == "curve") d->connectionType = Curve; else d->connectionType = Standard; // reset connection point indices d->connectionPointId1 = -1; d->connectionPointId2 = -1; // reset connected shapes d->shape1 = 0; d->shape2 = 0; if (element.hasAttributeNS(KoXmlNS::draw, "start-shape")) { d->connectionPointId1 = element.attributeNS(KoXmlNS::draw, "start-glue-point", QString()).toInt(); QString shapeId1 = element.attributeNS(KoXmlNS::draw, "start-shape", QString()); kDebug(30006) << "references start-shape" << shapeId1 << "at glue-point" << d->connectionPointId1; d->shape1 = context.shapeById(shapeId1); if (d->shape1) { kDebug(30006) << "start-shape was already loaded"; d->shape1->addDependee(this); if (d->shape1->hasConnectionPoint(d->connectionPointId1)) { kDebug(30006) << "connecting to start-shape"; d->handles[StartHandle] = d->shape1->absoluteTransformation(0).map(d->shape1->connectionPoint(d->connectionPointId1).position); kDebug(30006) << "start handle position =" << d->handles[StartHandle]; } } else { kDebug(30006) << "start-shape not loaded yet, deferring connection"; context.updateShape(shapeId1, new KoConnectionShapeLoadingUpdater(this, KoConnectionShapeLoadingUpdater::First)); } } else { d->handles[StartHandle].setX(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "x1", QString()))); d->handles[StartHandle].setY(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "y1", QString()))); } if (element.hasAttributeNS(KoXmlNS::draw, "end-shape")) { d->connectionPointId2 = element.attributeNS(KoXmlNS::draw, "end-glue-point", "").toInt(); QString shapeId2 = element.attributeNS(KoXmlNS::draw, "end-shape", ""); kDebug(30006) << "references end-shape " << shapeId2 << "at glue-point" << d->connectionPointId2; d->shape2 = context.shapeById(shapeId2); if (d->shape2) { kDebug(30006) << "end-shape was already loaded"; d->shape2->addDependee(this); if (d->shape2->hasConnectionPoint(d->connectionPointId2)) { kDebug(30006) << "connecting to end-shape"; d->handles[EndHandle] = d->shape2->absoluteTransformation(0).map(d->shape2->connectionPoint(d->connectionPointId2).position); kDebug(30006) << "end handle position =" << d->handles[EndHandle]; } } else { kDebug(30006) << "end-shape not loaded yet, deferring connection"; context.updateShape(shapeId2, new KoConnectionShapeLoadingUpdater(this, KoConnectionShapeLoadingUpdater::Second)); } } else { d->handles[EndHandle].setX(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "x2", QString()))); d->handles[EndHandle].setY(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "y2", QString()))); } QString skew = element.attributeNS(KoXmlNS::draw, "line-skew", QString()); QStringList skewValues = skew.simplified().split(' ', QString::SkipEmptyParts); // TODO apply skew values once we support them // load the path data if there is any d->hasCustomPath = element.hasAttributeNS(KoXmlNS::svg, "d"); if (d->hasCustomPath) { KoPathShapeLoader loader(this); loader.parseSvg(element.attributeNS(KoXmlNS::svg, "d"), true); if (m_subpaths.size() > 0) { QRectF viewBox = loadOdfViewbox(element); if (viewBox.isEmpty()) { // there should be a viewBox to transform the path data // if there is none, use the bounding rectangle of the parsed path viewBox = outline().boundingRect(); } // convert path to viewbox coordinates to have a bounding rect of (0,0 1x1) // which can later be fitted back into the target rect once we have all // the required information QTransform viewMatrix; viewMatrix.scale(viewBox.width() ? static_cast<qreal>(1.0) / viewBox.width() : 1.0, viewBox.height() ? static_cast<qreal>(1.0) / viewBox.height() : 1.0); viewMatrix.translate(-viewBox.left(), -viewBox.top()); d->map(viewMatrix); // trigger finishing the connections in case we have all data // otherwise it gets called again once the shapes we are // connected to are loaded } else { d->hasCustomPath = false; } finishLoadingConnection(); } else { d->forceUpdate = true; updateConnections(); } loadText(element, context); return true; }
bool EnhancedPathShape::loadOdf(const KXmlElement & element, KShapeLoadingContext &context) { reset(); loadOdfAttributes(element, context, OdfAdditionalAttributes | OdfCommonChildElements); const KXmlElement enhancedGeometry(KoXml::namedItemNS(element, KOdfXmlNS::draw, "enhanced-geometry" ) ); if (!enhancedGeometry.isNull()) { // load the modifiers QString modifiers = enhancedGeometry.attributeNS(KOdfXmlNS::draw, "modifiers"); if (!modifiers.isEmpty()) { addModifiers(modifiers); } KXmlElement grandChild; forEachElement(grandChild, enhancedGeometry) { if (grandChild.namespaceURI() != KOdfXmlNS::draw) continue; if (grandChild.localName() == "equation") { QString name = grandChild.attributeNS(KOdfXmlNS::draw, "name"); QString formula = grandChild.attributeNS(KOdfXmlNS::draw, "formula"); addFormula(name, formula); } else if (grandChild.localName() == "handle") { EnhancedPathHandle * handle = new EnhancedPathHandle(this); if (handle->loadOdf(grandChild, context)) { m_enhancedHandles.append(handle); evaluateHandles(); } else { delete handle; } } } setMirrorHorizontally(enhancedGeometry.attributeNS(KOdfXmlNS::draw, "mirror-horizontal") == "true"); setMirrorVertically(enhancedGeometry.attributeNS(KOdfXmlNS::draw, "mirror-vertical") == "true"); // load the enhanced path data QString path = enhancedGeometry.attributeNS(KOdfXmlNS::draw, "enhanced-path"); #ifndef NWORKAROUND_ODF_BUGS KOdfWorkaround::fixEnhancedPath(path, enhancedGeometry, context); #endif if (!path.isEmpty()) { parsePathData(path); } // load the viewbox QRectF viewBox = loadOdfViewbox(enhancedGeometry); if (! viewBox.isEmpty()) { m_viewBox = viewBox; } else { // if there is no view box defined make it is big as the path. m_viewBox = m_viewBound; } QString gluePoints(enhancedGeometry.attributeNS(KOdfXmlNS::draw, "glue-points")); if (!gluePoints.isEmpty()) { qreal x = -1; foreach (const QString &token, gluePoints.split(' ')) { if (x == -1) { // processing 'x' x = token.toInt(); } else { addConnectionPoint(QPointF(x, token.toInt())); x = -1; } } }