Skip to content

Commit 187642e

Browse files
committed
Copy and move functions.
1 parent 5972171 commit 187642e

File tree

2 files changed

+183
-28
lines changed

2 files changed

+183
-28
lines changed

addons/ofxSvg/src/ofxSvg.cpp

Lines changed: 160 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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
//--------------------------------------------------------------
48206
bool 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;

addons/ofxSvg/src/ofxSvg.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,33 @@
1212

1313
/// \file
1414
/// ofxSVG is used for loading, manipulating, rendering and saving of SVG files.
15+
/// Based on this spec: https://www.w3.org/TR/SVG/Overview.html
1516

16-
class ofxSvg : public ofxSvgGroup {
17-
public:
17+
class ofxSvg : public ofxSvgGroup {
18+
protected:
19+
std::shared_ptr<ofxSvgElement> clone( const std::shared_ptr<ofxSvgElement>& aele );
20+
std::vector<std::shared_ptr<ofxSvgElement>> deepCopyVector(const std::vector<std::shared_ptr<ofxSvgElement>>& original);
21+
void deepCopyFrom( const ofxSvg & mom );
22+
void moveFrom( ofxSvg&& mom );
1823

24+
public:
1925
virtual ofxSvgType getType() override {return ofxSvgType::TYPE_DOCUMENT;}
2026

27+
// Default constructor
28+
ofxSvg() = default;
29+
// Copy constructor (deep copy)
30+
ofxSvg(const ofxSvg & mom);// = default;
31+
// Copy assignment operator (deep copy)
32+
ofxSvg& operator=(const ofxSvg& mom);
33+
// Move constructor
34+
ofxSvg(ofxSvg&& mom);
35+
// Move assignment operator
36+
ofxSvg& operator=(ofxSvg&& mom);
37+
38+
~ofxSvg() = default;
39+
40+
ofxSvg(const of::filesystem::path & fileName);
41+
2142
/// \brief Loads an SVG file from the provided filename.
2243
/// \return true if the load was successful.
2344
bool load( const of::filesystem::path & fileName );

0 commit comments

Comments
 (0)