@@ -586,6 +586,12 @@ void ofxSvg::_parseXmlNode( ofXml& aParentNode, vector< shared_ptr<ofxSvgElement
586586shared_ptr<ofxSvgElement> ofxSvg::_addElementFromXmlNode ( ofXml& tnode, vector< shared_ptr<ofxSvgElement> >& aElements ) {
587587 shared_ptr<ofxSvgElement> telement;
588588
589+ bool bHasMatOrTrans = false ;
590+
591+ if (auto transAttr = tnode.getAttribute (" transform" ) ) {
592+ bHasMatOrTrans = true ;
593+ }
594+
589595 if ( tnode.getName () == " use" ) {
590596 if ( auto hrefAtt = tnode.getAttribute (" xlink:href" )) {
591597 ofLogVerbose (" ofxSvg" ) << " found a use node with href " << hrefAtt.getValue ();
@@ -635,47 +641,62 @@ shared_ptr<ofxSvgElement> ofxSvg::_addElementFromXmlNode( ofXml& tnode, vector<
635641
636642 } else if ( tnode.getName () == " ellipse" ) {
637643 auto ellipse = std::make_shared<ofxSvgEllipse>();
638- auto cxAttr = tnode.getAttribute (" cx" );
639644
640645 auto tpos = glm::vec2 (0 .f , 0 .f );
646+ auto cxAttr = tnode.getAttribute (" cx" );
641647 if (cxAttr) {tpos.x = cxAttr.getFloatValue ();}
642648 auto cyAttr = tnode.getAttribute (" cy" );
643649 if (cyAttr) {tpos.y = cyAttr.getFloatValue ();}
644650
645- ellipse->setPosition ( tpos.x , tpos.y , 0 .0f );
651+ if ( bHasMatOrTrans ) {
652+ ellipse->setOffsetPathPosition (tpos.x ,tpos.y );
653+ } else {
654+ ellipse->setPosition ( tpos.x , tpos.y , 0 .0f );
655+ }
656+
657+ glm::vec2 radii (0 .f , 0 .f );
646658
647- auto rxAttr = tnode.getAttribute ( " rx" );
648- if (rxAttr) ellipse->radiusX = rxAttr.getFloatValue ();
649- auto ryAttr = tnode.getAttribute ( " ry" );
650- if (ryAttr) ellipse->radiusY = ryAttr.getFloatValue ();
659+ if (auto rxAttr = tnode.getAttribute ( " rx" )) {
660+ radii.x = rxAttr.getFloatValue ();
661+ }
662+ if (auto ryAttr = tnode.getAttribute ( " ry" )) {
663+ radii.y = ryAttr.getFloatValue ();
664+ }
651665
652666 ellipse->path .setCircleResolution (mCircleResolution );
653667 ellipse->path .setCurveResolution (mCurveResolution );
654668 // make local so we can apply transform later in the function
655- ellipse->path .ellipse ({0 .f ,0 .f }, ellipse->radiusX * 2 .0f , ellipse->radiusY * 2 .0f );
669+ // ellipse->path.ellipse({0.f,0.f}, ellipse->radiusX * 2.0f, ellipse->radiusY * 2.0f );
670+ ellipse->setRadius (radii.x , radii.y );
656671
657672 _applyStyleToPath ( tnode, ellipse );
658673
659674 telement = ellipse;
660675 } else if ( tnode.getName () == " circle" ) {
661676 auto circle = std::make_shared<ofxSvgCircle>();
662677 auto tpos = glm::vec2 (0 .f , 0 .f );
678+
663679 if (auto cxAttr = tnode.getAttribute (" cx" )) {
664680 tpos.x = cxAttr.getFloatValue ();
665681 }
666682 if (auto cyAttr = tnode.getAttribute (" cy" )) {
667683 tpos.y = cyAttr.getFloatValue ();
668684 }
669- circle->setPosition (tpos.x , tpos.y , 0 .f );
670685
671- auto rAttr = tnode.getAttribute ( " r" );
672- if (rAttr) circle->radius = rAttr.getFloatValue ();
686+ if ( bHasMatOrTrans ) {
687+ circle->setOffsetPathPosition (tpos.x ,tpos.y );
688+ } else {
689+ circle->setPosition (tpos.x , tpos.y , 0 .f );
690+ }
673691
674692 // make local so we can apply transform later in the function
675693 // position is from the top left
676694 circle->path .setCircleResolution (mCircleResolution );
677695 circle->path .setCurveResolution (mCurveResolution );
678- circle->path .circle ({0 .f ,0 .f }, circle->radius );
696+ // circle->path.circle({0.f,0.f}, circle->radius );
697+ if (auto rAttr = tnode.getAttribute ( " r" )) {
698+ circle->setRadius (rAttr.getFloatValue ());
699+ }
679700
680701 _applyStyleToPath ( tnode, circle );
681702
@@ -720,39 +741,54 @@ shared_ptr<ofxSvgElement> ofxSvg::_addElementFromXmlNode( ofXml& tnode, vector<
720741
721742 auto tpos = glm::vec2 (0 .f , 0 .f );
722743 if (auto xattr = tnode.getAttribute (" x" )) {
723- tpos.x = xattr.getFloatValue ();
744+ tpos.x = xattr.getFloatValue ();
724745 }
725746 if (auto yattr = tnode.getAttribute (" y" )) {
726- tpos.y = yattr.getFloatValue ();
747+ tpos.y = yattr.getFloatValue ();
727748 }
728749 if (auto wattr = tnode.getAttribute (" width" )) {
729- rect->width = wattr.getFloatValue ();
750+ rect->width = wattr.getFloatValue ();
730751 }
731752 if (auto hattr = tnode.getAttribute (" height" )) {
732- rect->height = hattr.getFloatValue ();
753+ rect->height = hattr.getFloatValue ();
754+ }
755+
756+ if ( bHasMatOrTrans ) {
757+ rect->setOffsetPathPosition (tpos.x ,tpos.y );
758+ } else {
759+ rect->setPosition (tpos.x , tpos.y , 0 .0f );
733760 }
734- rect->setPosition (tpos.x , tpos.y , 0 .0f );
735761
736762 auto rxAttr = tnode.getAttribute (" rx" );
737763 auto ryAttr = tnode.getAttribute (" ry" );
738764
739765 rect->path .setCircleResolution (mCircleResolution );
740766 rect->path .setCurveResolution (mCurveResolution );
741767
742- // make local so we can apply transform later in the function
768+ float rRadius = 0 .0f ;
769+
743770 if ( !ofxSvgCssClass::sIsNone (rxAttr.getValue ()) || !ofxSvgCssClass::sIsNone (ryAttr.getValue ())) {
744- rect->roundRadius = -1 .f ; // force an update in setRoundRadius
745- rect->setRoundRadius (std::max (ofxSvgCssClass::sGetFloat (rxAttr.getValue ()),
746- ofxSvgCssClass::sGetFloat (ryAttr.getValue ()))
747- );
748- // rect->roundRadius = std::max(ofxSvgCssClass::sGetFloat(rxAttr.getValue()),
749- // ofxSvgCssClass::sGetFloat(ryAttr.getValue()));
750-
751- // rect->path.rectRounded(0.f, 0.f, rect->width, rect->height, rect->roundRadius);
752-
753- } else {
754- rect->path .rectangle (0 .f , 0 .f , rect->getWidth (), rect->getHeight ());
755- }
771+ rRadius = std::max (ofxSvgCssClass::sGetFloat (rxAttr.getValue ()),
772+ ofxSvgCssClass::sGetFloat (ryAttr.getValue ()));
773+ }
774+ rect->roundRadius = -1 .f ;
775+ rect->setRoundRadius (rRadius);
776+
777+ // // make local so we can apply transform later in the function
778+ // if( !ofxSvgCssClass::sIsNone(rxAttr.getValue()) || !ofxSvgCssClass::sIsNone(ryAttr.getValue())) {
779+ // rect->roundRadius = -1.f; // force an update in setRoundRadius
780+ // rect->setRoundRadius(std::max(ofxSvgCssClass::sGetFloat(rxAttr.getValue()),
781+ // ofxSvgCssClass::sGetFloat(ryAttr.getValue()))
782+ // );
783+ // // rect->roundRadius = std::max(ofxSvgCssClass::sGetFloat(rxAttr.getValue()),
784+ // // ofxSvgCssClass::sGetFloat(ryAttr.getValue()));
785+ // //
786+ // //
787+ // // rect->path.rectRounded(tpos.x, tpos.y, rect->width, rect->height, rect->roundRadius);
788+ //
789+ // } else {
790+ // rect->path.rectangle(tpos.x, tpos.y, rect->getWidth(), rect->getHeight());
791+ // }
756792
757793 telement = rect;
758794
@@ -887,6 +923,11 @@ shared_ptr<ofxSvgElement> ofxSvg::_addElementFromXmlNode( ofXml& tnode, vector<
887923 telement->layer = mCurrentLayer += 1.0 ;
888924 aElements.push_back ( telement );
889925
926+ if ( telement->getType () == OFXSVG_TYPE_RECTANGLE ) {
927+ auto rect = std::dynamic_pointer_cast<ofxSvgRectangle>( telement );
928+ ofLogNotice (" ofxSvg::_addElementFromXmlNode" ) << " rect->pos: " << rect->getGlobalPosition () << " shape: " << rect->getOffsetPathPosition ();
929+ }
930+
890931 if ( mGroupStack .size () > 0 ) {
891932 auto pgroup = mGroupStack .back ();
892933 ofLogVerbose (" ofxSvg::_addElementFromXmlNode" ) << " element: " << telement->getTypeAsString () << " -" << telement->getCleanName () << " - pos: " << telement->getPosition () << " - parent: " << pgroup->getCleanName ();
@@ -1878,7 +1919,7 @@ glm::mat4 ofxSvg::setTransformFromSvgMatrixString( string aStr, std::shared_ptr<
18781919// gmat = glm::translate(gmat, glm::vec3(tp.x, tp.y, 0.0f));
18791920// aele->pos.x = tp.x;
18801921// aele->pos.y = tp.y;
1881- // aele->setPosition(tp.x, tp.y, 0.0f);
1922+ aele->setPosition (tp.x , tp.y , 0 .0f );
18821923 } else {
18831924 mat = glm::translate (glm::mat4 (1 .0f ), glm::vec3 (0 .f , 0 .f , 0 .0f ));
18841925// gmat = glm::translate(gmat, glm::vec3(0.f, 0.f, 0.0f));
@@ -1938,7 +1979,7 @@ glm::mat4 ofxSvg::setTransformFromSvgMatrixString( string aStr, std::shared_ptr<
19381979// pos3 = gmat * glm::vec4( aele->pos.x, aele->pos.y, 0.0f, 1.f );
19391980// aele->pos.x = pos3.x;
19401981// aele->pos.y = pos3.y;
1941- aele->setPosition ( pos3.x , pos3.y , 0 .0f );
1982+ // aele->setPosition( pos3.x, pos3.y, 0.0f);
19421983
19431984// aele
19441985
@@ -2045,13 +2086,15 @@ std::string ofxSvg::getSvgMatrixStringFromElement( std::shared_ptr<ofxSvgElement
20452086 // matrix(1 0 0 1 352.4516 349.0799)">
20462087
20472088 std::ostringstream matrixStream;
2048- matrixStream << std::fixed << std::setprecision (6 );
2089+ matrixStream << std::fixed << std::setprecision (1 );
20492090 bool bFirst = true ;
20502091
2051- if ( aele->getPosition ().x != 0 .f || aele->getPosition ().y != 0 .f ) {
2052- bFirst = false ;
2053- matrixStream << " translate(" << aele->getPosition ().x << " ," << aele->getPosition ().y << " )" ;
2054- }
2092+ // if( aele->getType() != OFXSVG_TYPE_RECTANGLE && aele->getType() != OFXSVG_TYPE_CIRCLE && aele->getType() != OFXSVG_TYPE_ELLIPSE ) {
2093+ if ( aele->getPosition ().x != 0 .f || aele->getPosition ().y != 0 .f ) {
2094+ bFirst = false ;
2095+ matrixStream << " translate(" << aele->getPosition ().x << " ," << aele->getPosition ().y << " )" ;
2096+ }
2097+ // }
20552098 if ( aele->getRotationDeg () != 0 .f ) {
20562099 if (!bFirst) {
20572100 matrixStream << " " ;
@@ -2156,7 +2199,7 @@ void ofxSvg::_getTextSpanFromXmlNode( ofXml& anode, std::vector< std::shared_ptr
21562199
21572200 aspans.push_back (tspan);
21582201
2159- _pushCssClass (tspan->getCss ());
2202+ _pushCssClass (tspan->getCssClass ());
21602203 for ( auto & kid : anode.getChildren () ) {
21612204 if ( kid ) {
21622205 if ( kid.getName () == " tspan" ) {
@@ -2696,6 +2739,34 @@ void ofxSvg::_addCssClassFromImage( std::shared_ptr<ofxSvgImage> aSvgImage, ofXm
26962739 }
26972740}
26982741
2742+ // --------------------------------------------------------------
2743+ void ofxSvg::_addCssClassFromTextSpan ( std::shared_ptr<ofxSvgText::TextSpan> aSvgTextSpan, ofXml& anode ) {
2744+
2745+ auto textCss = aSvgTextSpan->getCssClass ();
2746+
2747+ if ( textCss.name .empty () ) {
2748+ textCss.name = " ts" ;
2749+ }
2750+
2751+ auto & tcss = mSvgCss .getAddClass (textCss);
2752+
2753+ if ( auto xattr = anode.appendAttribute (" class" ) ) {
2754+ xattr.set (tcss.name );
2755+ }
2756+
2757+ // if( !aSvgTextSpan->isVisible() ) {
2758+ // ofxSvgCssClass tcss;
2759+ // tcss.name = "st";
2760+ // tcss.addProperty("display", "none" );
2761+ //
2762+ // auto& addedClass = mSvgCss.getAddClass(tcss);
2763+ //
2764+ // if( auto xattr = anode.appendAttribute("class") ) {
2765+ // xattr.set(addedClass.name);
2766+ // }
2767+ // }
2768+ }
2769+
26992770// --------------------------------------------------------------
27002771bool ofxSvg::_toXml ( ofXml& aParentNode, std::shared_ptr<ofxSvgElement> aele ) {
27012772 ofXml txml = aParentNode.appendChild ( ofxSvgElement::sGetSvgXmlName (aele->getType ()));
@@ -2718,10 +2789,12 @@ bool ofxSvg::_toXml( ofXml& aParentNode, std::shared_ptr<ofxSvgElement> aele ) {
27182789 _addCssClassFromPath ( trect, txml );
27192790
27202791 if ( auto xattr = txml.appendAttribute (" x" )) {
2721- xattr.set (trect->getPosition ().x );
2792+ // xattr.set(trect->getPosition().x);
2793+ xattr.set (trect->getOffsetPathPosition ().x );
27222794 }
27232795 if ( auto xattr = txml.appendAttribute (" y" )) {
2724- xattr.set (trect->getPosition ().y );
2796+ // xattr.set(trect->getPosition().y);
2797+ xattr.set (trect->getOffsetPathPosition ().y );
27252798 }
27262799 if ( auto xattr = txml.appendAttribute (" width" )) {
27272800 xattr.set (trect->getWidth ());
@@ -2784,10 +2857,10 @@ bool ofxSvg::_toXml( ofXml& aParentNode, std::shared_ptr<ofxSvgElement> aele ) {
27842857 _addCssClassFromPath ( tellipse, txml );
27852858
27862859 if ( auto xattr = txml.appendAttribute (" cx" )) {
2787- xattr.set (tellipse->getPosition ().x );
2860+ xattr.set (tellipse->getOffsetPathPosition ().x );
27882861 }
27892862 if ( auto xattr = txml.appendAttribute (" cy" )) {
2790- xattr.set (tellipse->getPosition ().y );
2863+ xattr.set (tellipse->getOffsetPathPosition ().y );
27912864 }
27922865 if ( auto xattr = txml.appendAttribute (" rx" )) {
27932866 xattr.set (tellipse->radiusX );
@@ -2801,10 +2874,10 @@ bool ofxSvg::_toXml( ofXml& aParentNode, std::shared_ptr<ofxSvgElement> aele ) {
28012874 _addCssClassFromPath ( tcircle, txml );
28022875
28032876 if ( auto xattr = txml.appendAttribute (" cx" )) {
2804- xattr.set (tcircle->getPosition ().x );
2877+ xattr.set (tcircle->getOffsetPathPosition ().x );
28052878 }
28062879 if ( auto xattr = txml.appendAttribute (" cy" )) {
2807- xattr.set (tcircle->getPosition ().y );
2880+ xattr.set (tcircle->getOffsetPathPosition ().y );
28082881 }
28092882 if ( auto xattr = txml.appendAttribute (" r" )) {
28102883 xattr.set (tcircle->getRadius ());
@@ -2887,14 +2960,33 @@ bool ofxSvg::_toXml( ofXml& aParentNode, std::shared_ptr<ofxSvgElement> aele ) {
28872960
28882961 } else if ( aele->getType () == OFXSVG_TYPE_TEXT ) {
28892962 // TODO: Maybe at some point ;/
2963+ auto ttext = std::dynamic_pointer_cast<ofxSvgText>(aele);
2964+ for ( auto tspan : ttext->textSpans ) {
2965+ if ( auto spanXml = txml.appendChild (" tspan" )) {
2966+ if ( auto xattr = spanXml.appendAttribute (" x" )) {
2967+ xattr.set (tspan->rect .x );
2968+ }
2969+ if ( auto yattr = spanXml.appendAttribute (" y" )) {
2970+ yattr.set (tspan->rect .y );
2971+ }
2972+ spanXml.set (tspan->getText ());
2973+ _addCssClassFromTextSpan ( tspan, spanXml );
2974+ }
2975+ }
28902976 }
28912977
28922978 // figure out if we need a transform attribute
2893- if ( aele->getType () == OFXSVG_TYPE_IMAGE || aele->getRotationDeg () != 0 .0f || aele->getScale ().x != 1 .0f || aele->getScale ().y != 1 .0f ) {
2894- if ( auto xattr = txml.appendAttribute (" transform" )) {
2895- xattr.set ( getSvgMatrixStringFromElement (aele) );
2979+ // if( aele->getType() == OFXSVG_TYPE_IMAGE || aele->getRotationDeg() != 0.0f || aele->getScale().x != 1.0f || aele->getScale().y != 1.0f ) {
2980+ auto matrixString = getSvgMatrixStringFromElement (aele);
2981+ if ( !matrixString.empty () ) {
2982+ if ( auto xattr = txml.appendAttribute (" transform" )) {
2983+ xattr.set (matrixString);
2984+ }
28962985 }
2897- }
2986+ // if( auto xattr = txml.appendAttribute("transform")) {
2987+ // xattr.set( getSvgMatrixStringFromElement(aele) );
2988+ // }
2989+ // }
28982990 return txml;
28992991}
29002992
0 commit comments