diff options
Diffstat (limited to 'src/player/SVGElement.cpp')
-rw-r--r-- | src/player/SVGElement.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/player/SVGElement.cpp b/src/player/SVGElement.cpp new file mode 100644 index 0000000..dc0ba28 --- /dev/null +++ b/src/player/SVGElement.cpp @@ -0,0 +1,116 @@ +// +// libavg - Media Playback Engine. +// Copyright (C) 2003-2014 Ulrich von Zadow +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Current versions can be found at www.libavg.de +// + +#include "SVGElement.h" + +#include "../base/StringHelper.h" +#include "../base/Exception.h" +#include "../base/Logger.h" + +using namespace std; + +namespace avg { + +SVGElement::SVGElement(RsvgHandle* pRSVG, const UTF8String& sFilename, + const UTF8String& sElementID, bool bUnescapeIllustratorIDs) +{ + m_sUnescapedID = unescapeID(pRSVG, sFilename, sElementID, bUnescapeIllustratorIDs); + + RsvgPositionData pos; + rsvg_handle_get_position_sub(pRSVG, &pos, m_sUnescapedID.c_str()); + m_Pos = glm::vec2(pos.x, pos.y); + + RsvgDimensionData dim; + rsvg_handle_get_dimensions_sub(pRSVG, &dim, m_sUnescapedID.c_str()); + m_Size = glm::vec2(dim.width+1, dim.height+1); +} + +const UTF8String& SVGElement::getUnescapedID() const +{ + return m_sUnescapedID; +} + +const glm::vec2& SVGElement::getPos() const +{ + return m_Pos; +} + +const glm::vec2& SVGElement::getSize() const +{ + return m_Size; +} + +UTF8String SVGElement::unescapeID(RsvgHandle* pRSVG, const UTF8String& sFilename, + const UTF8String& sElementID, bool bUnescapeIllustratorIDs) +{ + UTF8String sResult(string("#") + sElementID); + if (bUnescapeIllustratorIDs) { + vector<string> sPossibleIDs; + sPossibleIDs.push_back(sResult); + string::size_type pos = sResult.find("_"); + if (pos != UTF8String::npos) { + while (pos != UTF8String::npos) { + sResult.replace(pos, 1, "_x5F_"); + pos = sResult.find("_", pos+5); + } + sPossibleIDs.push_back(sResult); + } + // Illustrator adds suffixes to IDs to get rid of duplicates. Even after the + // duplicates are removed, the suffixes remain :-(. + // We handle two cases here: + // 1) If there is only one version with a suffix, we take that version. + // 2) If there are duplicate IDs, we warn. + for (int i=1; i<30; ++i) { + string sTempID = sResult + "_" + toString(i) + "_"; + sPossibleIDs.push_back(sTempID); + } + int numFound = 0; + for (int i=0; i<30; ++i) { + string sTempID = sPossibleIDs[i]; + if (rsvg_handle_has_sub(pRSVG, sTempID.c_str())) { + sResult = sTempID; + numFound += 1; + } + } + if (numFound == 0) { + throwIDNotFound(sFilename, sElementID); + } + if (numFound > 1) { + AVG_LOG_WARNING("svg file '" << sFilename << + "' has more than one element with id '" << sElementID << "'."); + } + } else { + if (!rsvg_handle_has_sub(pRSVG, sResult.c_str())) { + throwIDNotFound(sFilename, sElementID); + } + } + return sResult; +} + +void SVGElement::throwIDNotFound(const UTF8String& sFilename, + const UTF8String& sElementID) +{ + throw Exception(AVG_ERR_INVALID_ARGS, + string("svg file '") + sFilename + "' does not have an element with id '" + + sElementID + "'."); +} + +} |