summaryrefslogtreecommitdiff
path: root/vcl/source/filter/idxf/dxfvec.cxx
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2021-02-15 11:35:38 +0900
committerTomaž Vajngerl <quikee@gmail.com>2021-02-17 09:55:46 +0100
commitd3476d27ab77160dcd737194fc13081ee297db16 (patch)
tree2d4fcbe510eae4bafeda332d7ba0093f248cc622 /vcl/source/filter/idxf/dxfvec.cxx
parent9d161857f1d4afcb772b477455797a2da0e47a9b (diff)
Move DXF reader from filter module into VCL
Change-Id: If1a933256401c1a971f581d1b389ca06fd77eaae Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111022 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl/source/filter/idxf/dxfvec.cxx')
-rw-r--r--vcl/source/filter/idxf/dxfvec.cxx234
1 files changed, 234 insertions, 0 deletions
diff --git a/vcl/source/filter/idxf/dxfvec.cxx b/vcl/source/filter/idxf/dxfvec.cxx
new file mode 100644
index 000000000000..fb1ff647d591
--- /dev/null
+++ b/vcl/source/filter/idxf/dxfvec.cxx
@@ -0,0 +1,234 @@
+/* -*- 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 <math.h>
+#include "dxfvec.hxx"
+#include <tools/gen.hxx>
+
+
+//---------------------------- DXFVector ---------------------------------------
+
+
+double DXFVector::Abs() const
+{
+ return sqrt(SProd(*this));
+}
+
+
+DXFVector DXFVector::Unit() const
+{
+ double flen;
+
+ flen=Abs();
+ if (flen!=0) return (*this)*(1.0/flen);
+ else return DXFVector(1.0,0.0,0.0);
+}
+
+
+//---------------------------- DXFTransform ------------------------------------
+
+
+DXFTransform::DXFTransform() :
+ aMX(1.0, 0.0, 0.0),
+ aMY(0.0, 1.0, 0.0),
+ aMZ(0.0, 0.0, 1.0),
+ aMP(0.0, 0.0, 0.0)
+{
+}
+
+
+DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
+ const DXFVector & rShift) :
+ aMX(fScaleX, 0.0, 0.0),
+ aMY(0.0, fScaleY, 0.0),
+ aMZ(0.0, 0.0, fScaleZ),
+ aMP(rShift)
+{
+}
+
+
+DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
+ double fRotAngle,
+ const DXFVector & rShift) :
+ aMX(0.0, 0.0, 0.0),
+ aMY(0.0, 0.0, 0.0),
+ aMZ(0.0, 0.0, fScaleZ),
+ aMP(rShift)
+{
+ aMX.fx=cos(3.14159265359/180.0*fRotAngle);
+ aMX.fy=sin(3.14159265359/180.0*fRotAngle);
+ aMY.fx=-aMX.fy;
+ aMY.fy=aMX.fx;
+ aMX*=fScaleX;
+ aMY*=fScaleY;
+}
+
+
+DXFTransform::DXFTransform(const DXFVector & rExtrusion) :
+ aMX(), aMY(), aMZ(), aMP(0.0, 0.0, 0.0)
+{
+ // 'Arbitrary Axis Algorithm' (cf. DXF documentation by Autodesk)
+ if ( fabs(rExtrusion.fx) < 1.0/64.0 && fabs(rExtrusion.fy) < 1.0/64.0) {
+ aMX = DXFVector(0.0, 1.0, 0.0) * rExtrusion;
+ }
+ else {
+ aMX = DXFVector(0.0, 0.0, 1.0) * rExtrusion;
+ }
+ aMX=aMX.Unit();
+ aMY=(rExtrusion*aMX).Unit();
+ aMZ=rExtrusion.Unit();
+}
+
+
+DXFTransform::DXFTransform(const DXFVector & rViewDir, const DXFVector & rViewTarget) :
+ aMX(), aMY(), aMZ(), aMP()
+{
+ DXFVector aV;
+
+ aV=rViewDir.Unit();
+ aMX.fz=aV.fx;
+ aMY.fz=aV.fy;
+ aMZ.fz=aV.fz;
+
+ aMZ.fx=0;
+ if (aV.fx==0) aMY.fx=0; else aMY.fx=sqrt(1/(1+aV.fy*aV.fy/(aV.fx*aV.fx)));
+ aMX.fx=sqrt(1-aMY.fx*aMY.fx);
+ if (aV.fx*aV.fy*aMY.fx>0) aMX.fx=-aMX.fx;
+
+ aV=aV*DXFVector(aMX.fx,aMY.fx,aMZ.fx);
+ aMX.fy=aV.fx;
+ aMY.fy=aV.fy;
+ aMZ.fy=aV.fz;
+
+ if (aMZ.fy<0) {
+ aMX.fy=-aMX.fy;
+ aMY.fy=-aMY.fy;
+ aMZ.fy=-aMZ.fy;
+ aMX.fx=-aMX.fx;
+ aMY.fx=-aMY.fx;
+ }
+
+ aV=DXFVector(0,0,0)-rViewTarget;
+ aMP.fx = aV.fx * aMX.fx + aV.fy * aMY.fx + aV.fz * aMZ.fx;
+ aMP.fy = aV.fx * aMX.fy + aV.fy * aMY.fy + aV.fz * aMZ.fy;
+ aMP.fz = aV.fx * aMX.fz + aV.fy * aMY.fz + aV.fz * aMZ.fz;
+}
+
+
+DXFTransform::DXFTransform(const DXFTransform & rT1, const DXFTransform & rT2) :
+ aMX(),aMY(),aMZ(),aMP()
+{
+ rT2.TransDir(rT1.aMX,aMX);
+ rT2.TransDir(rT1.aMY,aMY);
+ rT2.TransDir(rT1.aMZ,aMZ);
+ rT2.Transform(rT1.aMP,aMP);
+}
+
+
+void DXFTransform::Transform(const DXFVector & rSrc, DXFVector & rTgt) const
+{
+ rTgt.fx = rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx + aMP.fx;
+ rTgt.fy = rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy + aMP.fy;
+ rTgt.fz = rSrc.fx * aMX.fz + rSrc.fy * aMY.fz + rSrc.fz * aMZ.fz + aMP.fz;
+}
+
+
+void DXFTransform::Transform(const DXFVector & rSrc, Point & rTgt) const
+{
+ rTgt.setX(static_cast<tools::Long>( rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx + aMP.fx + 0.5 ) );
+ rTgt.setY(static_cast<tools::Long>( rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy + aMP.fy + 0.5 ) );
+}
+
+
+void DXFTransform::TransDir(const DXFVector & rSrc, DXFVector & rTgt) const
+{
+ rTgt.fx = rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx;
+ rTgt.fy = rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy;
+ rTgt.fz = rSrc.fx * aMX.fz + rSrc.fy * aMY.fz + rSrc.fz * aMZ.fz;
+}
+
+
+bool DXFTransform::TransCircleToEllipse(double fRadius, double & rEx, double & rEy) const
+{
+ double fMXAbs=aMX.Abs();
+ double fMYAbs=aMY.Abs();
+ double fNearNull=(fMXAbs+fMYAbs)*0.001;
+
+ if (fabs(aMX.fy)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
+ fabs(aMY.fx)<=fNearNull && fabs(aMY.fz)<=fNearNull)
+ {
+ rEx=fabs(aMX.fx*fRadius);
+ rEy=fabs(aMY.fy*fRadius);
+ return true;
+ }
+ else if (fabs(aMX.fx)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
+ fabs(aMY.fy)<=fNearNull && fabs(aMY.fz)<=fNearNull)
+ {
+ rEx=fabs(aMY.fx*fRadius);
+ rEy=fabs(aMX.fy*fRadius);
+ return true;
+ }
+ else if (fabs(fMXAbs-fMYAbs)<=fNearNull &&
+ fabs(aMX.fz)<=fNearNull && fabs(aMY.fz)<=fNearNull)
+ {
+ rEx=rEy=fabs(((fMXAbs+fMYAbs)/2)*fRadius);
+ return true;
+ }
+ else return false;
+}
+
+LineInfo DXFTransform::Transform(const DXFLineInfo& aDXFLineInfo) const
+{
+ double fex,fey,scale;
+
+ fex=sqrt(aMX.fx*aMX.fx + aMX.fy*aMX.fy);
+ fey=sqrt(aMY.fx*aMY.fx + aMY.fy*aMY.fy);
+ scale = (fex+fey)/2.0;
+
+ LineInfo aLineInfo;
+
+ aLineInfo.SetStyle( aDXFLineInfo.eStyle );
+ aLineInfo.SetWidth( 0 );
+ aLineInfo.SetDashCount( static_cast< sal_uInt16 >( aDXFLineInfo.nDashCount ) );
+ aLineInfo.SetDashLen( static_cast<sal_Int32>(aDXFLineInfo.fDashLen * scale + 0.5) );
+ aLineInfo.SetDotCount( static_cast< sal_uInt16 >( aDXFLineInfo.nDotCount ) );
+ aLineInfo.SetDotLen( static_cast<sal_Int32>(aDXFLineInfo.fDotLen * scale + 0.5) );
+ aLineInfo.SetDistance( static_cast<sal_Int32>(aDXFLineInfo.fDistance * scale + 0.5) );
+
+ if ( aLineInfo.GetDashCount() > 0 && aLineInfo.GetDashLen() == 0 )
+ aLineInfo.SetDashLen(1);
+
+ if ( aLineInfo.GetDotCount() > 0 && aLineInfo.GetDotLen() == 0 )
+ aLineInfo.SetDotLen(1);
+
+ return aLineInfo;
+}
+
+double DXFTransform::CalcRotAngle() const
+{
+ return atan2(aMX.fy,aMX.fx)/3.14159265359*180.0;
+}
+
+bool DXFTransform::Mirror() const
+{
+ return aMZ.SProd(aMX*aMY)<0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */