@@ -44,6 +44,164 @@ Measurement parseMeasurement(const std::string& input) {
4444 return result;
4545}
4646
47+ // --------------------------------------------------------------
48+ std::shared_ptr<ofxSvgElement> ofxSvg::clone ( const std::shared_ptr<ofxSvgElement>& aele ) {
49+ if (aele) {
50+ if ( aele->getType () == ofxSvgType::TYPE_ELEMENT ) {
51+ return std::make_shared<ofxSvgElement>(*aele);
52+ } else if ( aele->getType () == ofxSvgType::TYPE_GROUP ) {
53+ auto pg = std::dynamic_pointer_cast<ofxSvgGroup>(aele);
54+ return std::make_shared<ofxSvgGroup>(*pg);
55+ } else if ( aele->getType () == ofxSvgType::TYPE_RECTANGLE ) {
56+ auto pg = std::dynamic_pointer_cast<ofxSvgRectangle>(aele);
57+ return std::make_shared<ofxSvgRectangle>(*pg);
58+ } else if ( aele->getType () == ofxSvgType::TYPE_IMAGE ) {
59+ auto pg = std::dynamic_pointer_cast<ofxSvgImage>(aele);
60+ return std::make_shared<ofxSvgImage>(*pg);
61+ } else if ( aele->getType () == ofxSvgType::TYPE_ELLIPSE ) {
62+ auto pg = std::dynamic_pointer_cast<ofxSvgEllipse>(aele);
63+ return std::make_shared<ofxSvgEllipse>(*pg);
64+ } else if ( aele->getType () == ofxSvgType::TYPE_CIRCLE ) {
65+ auto pg = std::dynamic_pointer_cast<ofxSvgCircle>(aele);
66+ return std::make_shared<ofxSvgCircle>(*pg);
67+ } else if ( aele->getType () == ofxSvgType::TYPE_PATH ) {
68+ auto pg = std::dynamic_pointer_cast<ofxSvgPath>(aele);
69+ return std::make_shared<ofxSvgPath>(*pg);
70+ } else if ( aele->getType () == ofxSvgType::TYPE_TEXT ) {
71+ auto pg = std::dynamic_pointer_cast<ofxSvgText>(aele);
72+ return std::make_shared<ofxSvgText>(*pg);
73+ }
74+ }
75+ return std::shared_ptr<ofxSvgElement>();
76+ }
77+
78+ // Function to deep copy a vector of shared_ptrs
79+ std::vector<std::shared_ptr<ofxSvgElement>> ofxSvg::deepCopyVector (const std::vector<std::shared_ptr<ofxSvgElement>>& original) {
80+ std::vector<std::shared_ptr<ofxSvgElement>> copy;
81+ copy.reserve (original.size ()); // Reserve space for efficiency
82+
83+ for (auto ptr : original) {
84+ if (ptr) {
85+ copy.push_back (clone (ptr));
86+ } else {
87+ ofLogNotice (" ofxSvg" ) << " deepCopyVector :: nullptr" ;
88+ copy.push_back (std::shared_ptr<ofxSvgElement>()); // Preserve nullptr entries
89+ }
90+ }
91+ return copy;
92+ }
93+
94+ void ofxSvg::deepCopyFrom ( const ofxSvg & mom ) {
95+ if ( mom.mChildren .size () > 0 ) {
96+ mChildren = deepCopyVector (mom.mChildren );
97+ }
98+ ofLogNotice (" ofxSvg" ) << " deepCopyFrom mom num children: " << mom.mChildren .size () << " my size: " << mChildren .size ();
99+ if ( mom.mDefElements .size () > 0 ) {
100+ mDefElements = deepCopyVector (mom.mDefElements );
101+ }
102+
103+ mViewbox = mom.mViewbox ;
104+ mBounds = mom.mBounds ;
105+
106+ fontsDirectory = mom.fontsDirectory ;
107+ folderPath = mom.folderPath ;
108+ svgPath = mom.svgPath ;
109+
110+ mCurrentLayer = mom.mCurrentLayer ;
111+ mUnitStr = mom.mUnitStr ;
112+
113+ if (mom.mCurrentSvgCss ) {
114+ mCurrentSvgCss = std::make_shared<ofxSvgCssClass>(*mom.mCurrentSvgCss );
115+ }
116+
117+ mSvgCss = mom.mSvgCss ;
118+ mCurrentCss = mom.mCurrentCss ;
119+ mFillColor = mom.mFillColor ;
120+ mStrokeColor = mom.mStrokeColor ;
121+
122+ mModelMatrix = mom.mModelMatrix ;
123+ mModelMatrixStack = mom.mModelMatrixStack ;
124+
125+ mCircleResolution = mom.mCircleResolution ;
126+ mCurveResolution = mom.mCurveResolution ;
127+
128+ mPaths = mom.mPaths ;
129+ }
130+
131+ // --------------------------------------------------------------
132+ void ofxSvg::moveFrom ( ofxSvg&& mom ) {
133+ mChildren = std::move (mom.mChildren );
134+ mDefElements = std::move (mom.mDefElements );
135+
136+ mViewbox = mom.mViewbox ;
137+ mBounds = mom.mBounds ;
138+
139+ fontsDirectory = mom.fontsDirectory ;
140+ folderPath = mom.folderPath ;
141+ svgPath = mom.svgPath ;
142+
143+ mCurrentLayer = mom.mCurrentLayer ;
144+ mUnitStr = mom.mUnitStr ;
145+
146+ mCurrentSvgCss = mom.mCurrentSvgCss ;
147+
148+ mSvgCss = mom.mSvgCss ;
149+ mCurrentCss = mom.mCurrentCss ;
150+ mFillColor = mom.mFillColor ;
151+ mStrokeColor = mom.mStrokeColor ;
152+
153+ mModelMatrix = mom.mModelMatrix ;
154+ mModelMatrixStack = mom.mModelMatrixStack ;
155+
156+ mCircleResolution = mom.mCircleResolution ;
157+ mCurveResolution = mom.mCurveResolution ;
158+
159+ mPaths = mom.mPaths ;
160+ }
161+
162+
163+ // Copy constructor (deep copy)
164+ // --------------------------------------------------------------
165+ ofxSvg::ofxSvg (const ofxSvg & mom) {
166+ clear ();
167+ ofLogNotice (" ofxSvg" ) << " ofxSvg(const ofxSvg & mom)" ;
168+ deepCopyFrom (mom);
169+ }
170+
171+ // Copy assignment operator (deep copy)
172+ // --------------------------------------------------------------
173+ ofxSvg& ofxSvg::operator =(const ofxSvg& mom) {
174+ if (this != &mom) {
175+ ofLogNotice (" ofxSvg" ) << " ofxSvg::operator=(const ofxSvg& mom)" ;
176+ clear ();
177+ deepCopyFrom (mom);
178+ }
179+ return *this ;
180+ }
181+
182+ // Move constructor
183+ // --------------------------------------------------------------
184+ ofxSvg::ofxSvg (ofxSvg && mom) {
185+ ofLogNotice (" ofxSvg" ) << " ofxSvg(ofxSvg && mom)" ;
186+ clear ();
187+ moveFrom (std::move (mom));
188+ }
189+
190+ // Move assignment operator
191+ ofxSvg& ofxSvg::operator =(ofxSvg&& mom) {
192+ if (this != &mom) {
193+ ofLogNotice (" ofxSvg" ) << " ofxSvg::operator=(ofxSvg&& mom)" ;
194+ clear ();
195+ moveFrom (std::move (mom));
196+ }
197+ return *this ;
198+ }
199+
200+ // --------------------------------------------------------------
201+ ofxSvg::ofxSvg (const of::filesystem::path & fileName) {
202+ load (fileName);
203+ }
204+
47205// --------------------------------------------------------------
48206bool ofxSvg::load ( const of::filesystem::path& fileName ) {
49207 ofFile mainXmlFile ( fileName, ofFile::ReadOnly );
@@ -430,32 +588,8 @@ bool ofxSvg::_addElementFromXmlNode( ofXml& tnode, vector< shared_ptr<ofxSvgElem
430588 ofLogVerbose (" ofxSvg" ) << " going to look for href " << href;
431589 for ( auto & def : mDefElements ) {
432590 if ( def->name == href ) {
433- if ( def->getType () == ofxSvgType::TYPE_RECTANGLE ) {
434- auto drect = std::dynamic_pointer_cast<ofxSvgRectangle>(def);
435- auto nrect = std::make_shared<ofxSvgRectangle>( *drect );
436- telement = nrect;
437- } else if ( def->getType () == ofxSvgType::TYPE_IMAGE ) {
438- auto dimg = std::dynamic_pointer_cast<ofxSvgImage>(def);
439- auto nimg = std::make_shared<ofxSvgImage>( *dimg );
440- ofLogVerbose (" ofxSvg" ) << " created an image node with filepath: " << nimg->getFilePath ();
441- telement = nimg;
442- } else if ( def->getType () == ofxSvgType::TYPE_ELLIPSE ) {
443- auto dell= std::dynamic_pointer_cast<ofxSvgEllipse>(def);
444- auto nell = std::make_shared<ofxSvgEllipse>( *dell );
445- telement = nell;
446- } else if ( def->getType () == ofxSvgType::TYPE_CIRCLE ) {
447- auto dcir= std::dynamic_pointer_cast<ofxSvgCircle>(def);
448- auto ncir = std::make_shared<ofxSvgCircle>( *dcir );
449- telement = ncir;
450- } else if ( def->getType () == ofxSvgType::TYPE_PATH ) {
451- auto dpat= std::dynamic_pointer_cast<ofxSvgPath>(def);
452- auto npat = std::make_shared<ofxSvgPath>( *dpat );
453- telement = npat;
454- } else if ( def->getType () == ofxSvgType::TYPE_TEXT ) {
455- auto dtex = std::dynamic_pointer_cast<ofxSvgText>(def);
456- auto ntex = std::make_shared<ofxSvgText>( *dtex );
457- telement = ntex;
458- } else {
591+ telement = clone (def);
592+ if ( !telement ) {
459593 ofLogWarning (" Parser" ) << " could not find type for def : " << def->name ;
460594 }
461595 break ;
0 commit comments