summaryrefslogtreecommitdiffstats
path: root/svgio/source/svgreader/svgtextposition.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svgio/source/svgreader/svgtextposition.cxx')
-rw-r--r--svgio/source/svgreader/svgtextposition.cxx200
1 files changed, 200 insertions, 0 deletions
diff --git a/svgio/source/svgreader/svgtextposition.cxx b/svgio/source/svgreader/svgtextposition.cxx
new file mode 100644
index 0000000000..50a896ba22
--- /dev/null
+++ b/svgio/source/svgreader/svgtextposition.cxx
@@ -0,0 +1,200 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svgtextposition.hxx>
+
+using namespace drawinglayer::primitive2d;
+
+namespace svgio::svgreader
+{
+SvgTextPosition::SvgTextPosition(SvgTextPosition* pParent, const SvgTspanNode& rSvgTspanNode)
+ : mpParent(pParent)
+ , maRotate(solveSvgNumberVector(rSvgTspanNode.getRotate(), rSvgTspanNode))
+ , mfTextLength(0.0)
+ , mnRotationIndex(0)
+ , mbLengthAdjust(rSvgTspanNode.getLengthAdjust())
+ , mbAbsoluteX(false)
+{
+ const InfoProvider& rInfoProvider(rSvgTspanNode);
+
+ // get TextLength if provided
+ if (rSvgTspanNode.getTextLength().isSet())
+ {
+ mfTextLength = rSvgTspanNode.getTextLength().solve(rInfoProvider);
+ }
+
+ // SVG does not really define in which units a \91rotate\92 for Text/TSpan is given,
+ // but it seems to be degrees. Convert here to radians
+ if (!maRotate.empty())
+ {
+ for (double& f : maRotate)
+ {
+ f = basegfx::deg2rad(f);
+ }
+ }
+
+ // get text positions X
+ const sal_uInt32 nSizeX(rSvgTspanNode.getX().size());
+
+ if (nSizeX)
+ {
+ // we have absolute positions, get first one as current text position X
+ maPosition.setX(rSvgTspanNode.getX()[0].solve(rInfoProvider, NumberType::xcoordinate));
+ mbAbsoluteX = true;
+ }
+ else
+ {
+ // no absolute position, get from parent
+ if (pParent)
+ {
+ maPosition.setX(pParent->getPosition().getX());
+ }
+ }
+
+ const sal_uInt32 nSizeDx(rSvgTspanNode.getDx().size());
+ if (nSizeDx)
+ {
+ // relative positions given, translate position derived from parent
+ maPosition.setX(maPosition.getX()
+ + rSvgTspanNode.getDx()[0].solve(rInfoProvider, NumberType::xcoordinate));
+ }
+
+ // fill deltas to maX
+ maX.reserve(nSizeX);
+
+ for (sal_uInt32 a(1); a < std::max(nSizeX, nSizeDx); ++a)
+ {
+ if (a < nSizeX)
+ {
+ double nPos = rSvgTspanNode.getX()[a].solve(rInfoProvider, NumberType::xcoordinate)
+ - maPosition.getX();
+
+ if (a < nSizeDx)
+ {
+ nPos += rSvgTspanNode.getDx()[a].solve(rInfoProvider, NumberType::xcoordinate);
+ }
+
+ maX.push_back(nPos);
+ }
+ else
+ {
+ // Apply them later since it also needs the character width to calculate
+ // the final character position
+ maDx.push_back(rSvgTspanNode.getDx()[a].solve(rInfoProvider, NumberType::xcoordinate));
+ }
+ }
+
+ // get text positions Y
+ const sal_uInt32 nSizeY(rSvgTspanNode.getY().size());
+
+ if (nSizeY)
+ {
+ // we have absolute positions, get first one as current text position Y
+ maPosition.setY(rSvgTspanNode.getY()[0].solve(rInfoProvider, NumberType::ycoordinate));
+ mbAbsoluteX = true;
+ }
+ else
+ {
+ // no absolute position, get from parent
+ if (pParent)
+ {
+ maPosition.setY(pParent->getPosition().getY());
+ }
+ }
+
+ const sal_uInt32 nSizeDy(rSvgTspanNode.getDy().size());
+
+ if (nSizeDy)
+ {
+ // relative positions given, translate position derived from parent
+ maPosition.setY(maPosition.getY()
+ + rSvgTspanNode.getDy()[0].solve(rInfoProvider, NumberType::ycoordinate));
+ }
+
+ // fill deltas to maY
+ maY.reserve(nSizeY);
+
+ for (sal_uInt32 a(1); a < nSizeY; a++)
+ {
+ double nPos = rSvgTspanNode.getY()[a].solve(rInfoProvider, NumberType::ycoordinate)
+ - maPosition.getY();
+
+ if (a < nSizeDy)
+ {
+ nPos += rSvgTspanNode.getDy()[a].solve(rInfoProvider, NumberType::ycoordinate);
+ }
+
+ maY.push_back(nPos);
+ }
+}
+
+bool SvgTextPosition::isRotated() const
+{
+ if (maRotate.empty())
+ {
+ if (getParent())
+ {
+ return getParent()->isRotated();
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return true;
+ }
+}
+
+double SvgTextPosition::consumeRotation()
+{
+ double fRetval(0.0);
+
+ if (maRotate.empty())
+ {
+ if (getParent())
+ {
+ fRetval = mpParent->consumeRotation();
+ }
+ else
+ {
+ fRetval = 0.0;
+ }
+ }
+ else
+ {
+ const sal_uInt32 nSize(maRotate.size());
+
+ if (mnRotationIndex < nSize)
+ {
+ fRetval = maRotate[mnRotationIndex++];
+ }
+ else
+ {
+ fRetval = maRotate[nSize - 1];
+ }
+ }
+
+ return fRetval;
+}
+
+} // end of namespace svgio
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */