odf.cpp revision e4a9f366dbcb54f76b8c42869fa6873808132357
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * OpenDocument <drawing> input and output
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * This is an an entry in the extensions mechanism to begin to enable
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * the inputting and outputting of OpenDocument Format (ODF) files from
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz * within Inkscape. Although the initial implementations will be very lossy
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * do to the differences in the models of SVG and ODF, they will hopefully
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * improve greatly with time. People should consider this to be a framework
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * that can be continously upgraded for ever improving fidelity. Potential
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * developers should especially look in preprocess() and writeTree() to see how
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * the SVG tree is scanned, read, translated, and then written to ODF.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Bob Jamison
75b857d473541532819bd791105cb352c9a43214buliabyak * Copyright (C) 2006, 2007 Bob Jamison
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * This library is free software; you can redistribute it and/or
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * modify it under the terms of the GNU Lesser General Public
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * License as published by the Free Software Foundation; either
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * version 2.1 of the License, or (at your option) any later version.
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * This library is distributed in the hope that it will be useful,
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * but WITHOUT ANY WARRANTY; without even the implied warranty of
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Lesser General Public License for more details.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * You should have received a copy of the GNU Lesser General Public
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * License along with this library; if not, write to the Free Software
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh//# System includes
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh//# Inkscape includes
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh//# DOM-specific includes
cb814cb0df20053ca3ef16ce55da474435daf045miklosh//# Shorthand notation
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshtypedef org::w3c::dom::io::OutputStreamWriter OutputStreamWriter;
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshtypedef org::w3c::dom::io::BufferOutputStream BufferOutputStream;
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshtypedef org::w3c::dom::io::StringOutputStream StringOutputStream;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh//########################################################################
68664e00e2372534b4df2fdc5f54f836bafece18miklosh//# C L A S S SingularValueDecomposition
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh//########################################################################
1667116521643e2475184b048e0abb77a2aa9735miklosh SVDMatrix(unsigned int rowSize, unsigned int colSize)
75b857d473541532819bd791105cb352c9a43214buliabyak d = new double[size];
75b857d473541532819bd791105cb352c9a43214buliabyak for (unsigned int i=0 ; i<size ; i++)
84d6d1f7365e49f2936df9df890ce49d2c000ce2Kris SVDMatrix(double *vals, unsigned int rowSize, unsigned int colSize)
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh d = new double[size];
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh for (unsigned int i=0 ; i<size ; i++)
68664e00e2372534b4df2fdc5f54f836bafece18miklosh return *this;
68664e00e2372534b4df2fdc5f54f836bafece18miklosh delete[] d;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh double& operator() (unsigned int row, unsigned int col)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double operator() (unsigned int row, unsigned int col) const
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh unsigned int getRows()
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh unsigned int getCols()
1667116521643e2475184b048e0abb77a2aa9735miklosh for (unsigned int i=0 ; i<rows ; i++)
1667116521643e2475184b048e0abb77a2aa9735miklosh for (unsigned int k=0 ; k<cols ; k++)
1667116521643e2475184b048e0abb77a2aa9735miklosh //sum += a[i][k] * b[k][j];
68664e00e2372534b4df2fdc5f54f836bafece18miklosh for (unsigned int i=0 ; i<rows ; i++)
68664e00e2372534b4df2fdc5f54f836bafece18miklosh for (unsigned int j=0 ; j<cols ; j++)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh virtual void init()
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh delete[] d;
fba63a357654d8b3e84c60007e40aa698cd45d19miklosh d = new double[size];
d9a7c806ee7f408ddb61ff4f233c9d96111ee2b5johanengelen for (unsigned int i=0 ; i<size ; i++)
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh unsigned int rows;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh unsigned int cols;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh unsigned int size;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * ====================================================
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * This class is ported almost verbatim from the public domain
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * JAMA Matrix package. It is modified to handle only 3x3 matrices
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * and our NR::Matrix affine transform class. We give full
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * attribution to them, along with many thanks. JAMA can be found at:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * ====================================================
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Singular Value Decomposition.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * For an m-by-n matrix A with m >= n, the singular value decomposition is
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * an n-by-n orthogonal matrix V so that A = U*S*V'.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * The singular values, sigma[k] = S[k][k], are ordered so that
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * sigma[0] >= sigma[1] >= ... >= sigma[n-1].
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * The singular value decompostion always exists, so the constructor will
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * never fail. The matrix condition number and the effective numerical
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * rank can be computed from this decomposition.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh /** Construct the singular value decomposition
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh @param A Rectangular matrix
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh @return Structure to access U, S and V.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh delete[] s;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * Return the left singular vectors
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * @return U
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh * Return the right singular vectors
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * @return V
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Return the s[index] value
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * @return max(S)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Two norm condition number
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * @return max(S)/min(S)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Effective numerical matrix rank
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * @return Number of nonnegligible singular values.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh unsigned int s_size;
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshstatic double svd_hypot(double a, double b)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh else if (b != 0)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Initialize.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh int m = A.getRows();
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh int n = A.getCols();
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh int nu = (m > n) ? m : n;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh s = new double[s_size];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double *e = new double[n];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double *work = new double[m];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh bool wantu = true;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh bool wantv = true;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Reduce A to bidiagonal form, storing the diagonal elements
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // in s and the super-diagonal elements in e.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int k = 0; k < 2; k++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Compute the transformation for the k-th column and
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // place the k-th diagonal in s[k].
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Compute 2-norm of k-th column without under/overflow.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = k; i < m; i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh s[k] = svd_hypot(s[k],A(i, k));
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if (s[k] != 0.0) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if (A(k, k) < 0.0) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh s[k] = -s[k];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = k; i < m; i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh A(i, k) /= s[k];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh A(k, k) += 1.0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh s[k] = -s[k];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int j = k+1; j < n; j++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Apply the transformation.
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double t = 0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = k; i < m; i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh t += A(i, k) * A(i, j);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh t = -t/A(k, k);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = k; i < m; i++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh A(i, j) += t*A(i, k);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Place the k-th row of A into e for the
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // subsequent calculation of the row transformation.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh e[j] = A(k, j);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Place the transformation in U for subsequent back
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // multiplication.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = k; i < m; i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh U(i, k) = A(i, k);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Compute the k-th row transformation and place the
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // k-th super-diagonal in e[k].
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Compute 2-norm without under/overflow.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = k+1; i < n; i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh e[k] = svd_hypot(e[k],e[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if (e[k] != 0.0) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh e[k] = -e[k];
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh for (int i = k+1; i < n; i++) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh e[i] /= e[k];
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh e[k] = -e[k];
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh // Apply the transformation.
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh for (int i = k+1; i < m; i++) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh for (int j = k+1; j < n; j++) {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh for (int i = k+1; i < m; i++) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh work[i] += e[j]*A(i, j);
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh for (int j = k+1; j < n; j++) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh double t = -e[j]/e[k+1];
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh for (int i = k+1; i < m; i++) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh A(i, j) += t*work[i];
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh // Place the transformation in V for subsequent
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh // back multiplication.
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh for (int i = k+1; i < n; i++) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh V(i, k) = e[i];
1db439af43130c9695dbbb661e893d56006bb072miklosh // Set up the final bidiagonal matrix or order p.
1db439af43130c9695dbbb661e893d56006bb072miklosh if (m < p) {
1db439af43130c9695dbbb661e893d56006bb072miklosh // If required, generate U.
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh for (int i = 0; i < m; i++) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh U(i, j) = 0.0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh U(j, j) = 1.0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if (s[k] != 0.0) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double t = 0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = k; i < m; i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh t += U(i, k)*U(i, j);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh t = -t/U(k, k);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = k; i < m; i++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh U(i, j) += t*U(i, k);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int i = k; i < m; i++ ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh U(i, k) = -U(i, k);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh U(k, k) = 1.0 + U(k, k);
920fbbf5386a5d3b1d0a1304cb71eb48112abe0dmiklosh for (int i = 0; i < k-1; i++) {
920fbbf5386a5d3b1d0a1304cb71eb48112abe0dmiklosh U(i, k) = 0.0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = 0; i < m; i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh U(i, k) = 0.0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh U(k, k) = 1.0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // If required, generate V.
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int k = n-1; k >= 0; k--) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double t = 0;
d37634d73670180f99a3e0ea583621373d90ec4fJohan Engelen for (int i = k+1; i < n; i++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh t += V(i, k)*V(i, j);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh t = -t/V(k+1, k);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int i = k+1; i < n; i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh V(i, j) += t*V(i, k);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = 0; i < n; i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh V(i, k) = 0.0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh V(k, k) = 1.0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Main iteration loop for the singular values.
f9325af537ca5517eb50ef95f432a3204616f6b3apenner //double eps = pow(2.0,-52.0);
f9325af537ca5517eb50ef95f432a3204616f6b3apenner //double tiny = pow(2.0,-966.0);
f9325af537ca5517eb50ef95f432a3204616f6b3apenner //let's just calculate these now
f9325af537ca5517eb50ef95f432a3204616f6b3apenner //a double can be e � 308.25, so this is safe
f9325af537ca5517eb50ef95f432a3204616f6b3apenner while (p > 0) {
f9325af537ca5517eb50ef95f432a3204616f6b3apenner // Here is where a test for too many iterations would go.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // This section of the program inspects for
dd6d813ffad339352c39dc0645a792bdd9d8315cmiklosh // negligible elements in the s and e arrays. On
dd6d813ffad339352c39dc0645a792bdd9d8315cmiklosh // completion the variables kase and k are set as follows.
dd6d813ffad339352c39dc0645a792bdd9d8315cmiklosh // kase = 1 if s(p) and e[k-1] are negligible and k<p
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // kase = 2 if s(k) is negligible and k<p
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // kase = 3 if e[k-1] is negligible, k<p, and
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // s(k), ..., s(p) are not negligible (qr step).
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // kase = 4 if e(p-1) is negligible (convergence).
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if (k == -1) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if (fabs(e[k]) <=
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh e[k] = 0.0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if (k == p-2) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if (ks == k) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if (ks == k) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh // Perform the task indicated by kase.
f9325af537ca5517eb50ef95f432a3204616f6b3apenner // Deflate negligible s(p).
f9325af537ca5517eb50ef95f432a3204616f6b3apenner double f = e[p-2];
f9325af537ca5517eb50ef95f432a3204616f6b3apenner for (int j = p-2; j >= k; j--) {
f9325af537ca5517eb50ef95f432a3204616f6b3apenner double t = svd_hypot(s[j],f);
f9325af537ca5517eb50ef95f432a3204616f6b3apenner double cs = s[j]/t;
f9325af537ca5517eb50ef95f432a3204616f6b3apenner double sn = f/t;
f9325af537ca5517eb50ef95f432a3204616f6b3apenner if (j != k) {
f9325af537ca5517eb50ef95f432a3204616f6b3apenner for (int i = 0; i < n; i++) {
f9325af537ca5517eb50ef95f432a3204616f6b3apenner V(i, j) = t;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Split at negligible s(k).
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double f = e[k-1];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int j = k; j < p; j++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double t = svd_hypot(s[j],f);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double cs = s[j]/t;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double sn = f/t;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh e[j] = cs*e[j];
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh for (int i = 0; i < m; i++) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh U(i, j) = t;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh // Perform one qr step.
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh // Calculate the shift.
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh double b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh if (b < 0.0) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh // Chase zeros.
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh for (int j = k; j < p-1; j++) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh double t = svd_hypot(f,g);
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh double cs = f/t;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh double sn = g/t;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh if (j != k) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh e[j-1] = t;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = 0; i < n; i++) {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh V(i, j) = t;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int i = 0; i < m; i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh U(i, j) = t;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh e[p-2] = f;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Convergence.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Make the singular values positive.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if (s[k] <= 0.0) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = 0; i <= pp; i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh V(i, k) = -V(i, k);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // Order the singular values.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh while (k < pp) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if (s[k] >= s[k+1]) {
d37634d73670180f99a3e0ea583621373d90ec4fJohan Engelen double t = s[k];
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh s[k] = s[k+1];
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh s[k+1] = t;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh for (int i = 0; i < n; i++) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh for (int i = 0; i < m; i++) {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh * Return the left singular vectors
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh * @return U
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh * Return the right singular vectors
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh * @return V
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Return the s[0] value
d27f5758e12c3107ee69e66702043931e0756f6bmikloshdouble SingularValueDecomposition::getS(unsigned int index)
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh return 0.0;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh * @return max(S)
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh return s[0];
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh * Two norm condition number
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh * @return max(S)/min(S)
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh return s[0]/s[2];
8ec52d39f409ecf67125cd4d878b844e9391e7e8miklosh * Effective numerical matrix rank
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh * @return Number of nonnegligible singular values.
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh for (int i = 0; i < 3; i++)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if (s[i] > tol)
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh//########################################################################
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh//# E N D C L A S S SingularValueDecomposition
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh//########################################################################
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh//#define pxToCm 0.0275
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh//########################################################################
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh//# O U T P U T
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh//########################################################################
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Get the value of a node/attribute pair
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshstatic Glib::ustring getAttribute( Inkscape::XML::Node *node, char const *attrName)
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * Get the extension suffix from the end of a file name
3711b3e25395437ee0a09dbbb2a76d999c4ef322mikloshstatic Glib::ustring getExtension(const Glib::ustring &fname)
75b857d473541532819bd791105cb352c9a43214buliabyakstatic Glib::ustring formatTransform(NR::Matrix &tf)
75b857d473541532819bd791105cb352c9a43214buliabyak out.printf("matrix(%.3f %.3f %.3f %.3f %.3f %.3f)",
75b857d473541532819bd791105cb352c9a43214buliabyak * Get the general transform from SVG pixels to
75b857d473541532819bd791105cb352c9a43214buliabyakstatic NR::Matrix getODFTransform(const SPItem *item)
75b857d473541532819bd791105cb352c9a43214buliabyak //### Get SVG-to-ODF transform
75b857d473541532819bd791105cb352c9a43214buliabyak //Flip Y into document coordinates
75b857d473541532819bd791105cb352c9a43214buliabyak double doc_height = sp_document_height(SP_ACTIVE_DOCUMENT);
75b857d473541532819bd791105cb352c9a43214buliabyak NR::Matrix doc2dt_tf = NR::Matrix(NR::scale(1.0, -1.0));
75b857d473541532819bd791105cb352c9a43214buliabyak doc2dt_tf = doc2dt_tf * NR::Matrix(NR::translate(0, doc_height));
75b857d473541532819bd791105cb352c9a43214buliabyak * Get the bounding box of an item, as mapped onto
75b857d473541532819bd791105cb352c9a43214buliabyak * an ODF document, in cm.
75b857d473541532819bd791105cb352c9a43214buliabyakstatic NR::Maybe<NR::Rect> getODFBoundingBox(const SPItem *item)
75b857d473541532819bd791105cb352c9a43214buliabyak NR::Maybe<NR::Rect> bbox = sp_item_bbox_desktop((SPItem *)item);
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh double doc_height = sp_document_height(SP_ACTIVE_DOCUMENT);
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh NR::Matrix doc2dt_tf = NR::Matrix(NR::scale(1.0, -1.0));
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh doc2dt_tf = doc2dt_tf * NR::Matrix(NR::translate(0, doc_height));
0e14f9e966c4b6012538d30cd0db7a775b879760JucaBlues * Get the transform for an item, correcting for
0e14f9e966c4b6012538d30cd0db7a775b879760JucaBlues * handedness reversal
0e14f9e966c4b6012538d30cd0db7a775b879760JucaBluesstatic NR::Matrix getODFItemTransform(const SPItem *item)
0e14f9e966c4b6012538d30cd0db7a775b879760JucaBlues NR::Matrix itemTransform = NR::Matrix(NR::scale(1, -1));
0e14f9e966c4b6012538d30cd0db7a775b879760JucaBlues itemTransform = itemTransform * NR::Matrix(NR::scale(1, -1));
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * Get some fun facts from the transform
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh double &rotate, double &/*xskew*/, double &/*yskew*/,
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //g_message("## s0:%.3f s1:%.3f", s0, s1);
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh //g_message("## u:%.3f %.3f %.3f %.3f", U(0,0), U(0,1), U(1,0), U(1,1));
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //g_message("## v:%.3f %.3f %.3f %.3f", V(0,0), V(0,1), V(1,0), V(1,1));
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //g_message("## vt:%.3f %.3f %.3f %.3f", Vt(0,0), Vt(0,1), Vt(1,0), Vt(1,1));
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //g_message("## uvt:%.3f %.3f %.3f %.3f", UVt(0,0), UVt(0,1), UVt(1,0), UVt(1,1));
77364929ced3ec0bc5c9f47440606615c559084emikloshstatic void gatherText(Inkscape::XML::Node *node, Glib::ustring &buf)
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (Inkscape::XML::Node *child = node->firstChild() ;
75b857d473541532819bd791105cb352c9a43214buliabyak * FIRST PASS.
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * Method descends into the repr tree, converting image, style, and gradient info
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * into forms compatible in ODF.
3711b3e25395437ee0a09dbbb2a76d999c4ef322mikloshOdfOutput::preprocess(ZipFile &zf, Inkscape::XML::Node *node)
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh //### First, check for metadata
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh if (nodeName == "metadata" || nodeName == "svg:metadata")
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh Inkscape::XML::Node *rchild = mchild->firstChild() ;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh for (Inkscape::XML::Node *cchild = rchild->firstChild() ;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //g_message("ccName: %s ccVal:%s", ccName.c_str(), ccVal.c_str());
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh //Now consider items.
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh SPObject *reprobj = SP_ACTIVE_DOCUMENT->getObjectByRepr(node);
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh //### Get SVG-to-ODF transform
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh //g_message("image");
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh Glib::ustring href = getAttribute(node, "xlink:href");
0e14f9e966c4b6012538d30cd0db7a775b879760JucaBlues //g_message("oldpath:%s", oldUri.getNativePath().c_str());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //# if relative to the documentURI, get proper path
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //g_message("native path:%s", pathName.c_str());
0e14f9e966c4b6012538d30cd0db7a775b879760JucaBlues g_warning("Could not load image file '%s'", pathName.c_str());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (Inkscape::XML::Node *child = node->firstChild() ;
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh * Writes the manifest. Currently it only changes according to the
fd39535b3a5276f8962a3f99072668f3e63421edmiklosh * file names of images packed into the zip file.
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("<!DOCTYPE manifest:manifest PUBLIC \"-//OpenOffice.org//DTD Manifest 1.0//EN\" \"Manifest.dtd\">\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("*************************************************************************\n");
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh outs.printf(" Generated by Inkscape: %s", ctime(&tim)); //ctime has its own <cr>
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh outs.printf("*************************************************************************\n");
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh outs.printf("<manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\">\n");
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh outs.printf(" <manifest:file-entry manifest:media-type=\"application/vnd.oasis.opendocument.graphics\" manifest:full-path=\"/\"/>\n");
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh outs.printf(" <manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"content.xml\"/>\n");
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh outs.printf(" <manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"styles.xml\"/>\n");
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh outs.printf(" <manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"meta.xml\"/>\n");
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh std::map<Glib::ustring, Glib::ustring>::iterator iter;
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh for (iter = imageTable.begin() ; iter!=imageTable.end() ; iter++)
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh outs.printf(" <manifest:file-entry manifest:media-type=\"");
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh //Make our entry
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh ZipEntry *ze = zf.newEntry("META-INF/manifest.xml", "ODF file manifest");
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh return true;
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh * This writes the document meta information to meta.xml
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh std::map<Glib::ustring, Glib::ustring>::iterator iter;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("*************************************************************************\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" Generated by Inkscape: %s", ctime(&tim)); //ctime has its own <cr>
d37634d73670180f99a3e0ea583621373d90ec4fJohan Engelen outs.printf("*************************************************************************\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n");
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh outs.printf("xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\"\n");
17d87f5698f5c2958d38c6a6207c7b322a7adaf9johanengelen outs.printf("xmlns:presentation=\"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0\"\n");
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh outs.printf("xmlns:ooo=\"http://openoffice.org/2004/office\"\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("xmlns:smil=\"urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0\"\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("xmlns:anim=\"urn:oasis:names:tc:opendocument:xmlns:animation:1.0\"\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <meta:generator>Inkscape.org - 0.45</meta:generator>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <meta:initial-creator>%#s</meta:initial-creator>\n",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <meta:creation-date>%#s</meta:creation-date>\n", date.c_str());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (iter = metadata.begin() ; iter != metadata.end() ; iter++)
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <meta:editing-cycles>2</meta:editing-cycles>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <meta:editing-duration>PT56S</meta:editing-duration>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <meta:user-defined meta:name=\"Info 1\"/>\n");
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh outs.printf(" <meta:user-defined meta:name=\"Info 2\"/>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <meta:user-defined meta:name=\"Info 3\"/>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <meta:user-defined meta:name=\"Info 4\"/>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <meta:document-statistic meta:object-count=\"2\"/>\n");
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh //Make our entry
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh ZipEntry *ze = zf.newEntry("meta.xml", "ODF info file");
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh return true;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * This is called just before writeTree(), since it will write style and
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * gradient information above the <draw> tag in the content.xml file
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh ==========================================================
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh Dump our style table. Styles should have a general layout
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh something like the following. Look in:
5834db43b21308e958a2fdbbec082b1a4f019a38bryce http://books.evc-cit.info/odbook/ch06.html#draw-style-file-section
5834db43b21308e958a2fdbbec082b1a4f019a38bryce for style and gradient information.
5834db43b21308e958a2fdbbec082b1a4f019a38bryce <style:style style:name="gr13"
5834db43b21308e958a2fdbbec082b1a4f019a38bryce style:family="graphic" style:parent-style-name="standard">
5834db43b21308e958a2fdbbec082b1a4f019a38bryce <style:graphic-properties draw:stroke="solid"
5834db43b21308e958a2fdbbec082b1a4f019a38bryce svg:stroke-width="0.1cm"
5834db43b21308e958a2fdbbec082b1a4f019a38bryce svg:stroke-color="#ff0000"
75b857d473541532819bd791105cb352c9a43214buliabyak draw:fill="solid" draw:fill-color="#e6e6ff"/>
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh </style:style>
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh ==========================================================
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh outs.printf("<!-- ####### Styles from Inkscape document ####### -->\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (iter = styleTable.begin() ; iter != styleTable.end() ; iter++)
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("<style:style style:name=\"%s\"", iter->name.c_str());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" style:family=\"graphic\" style:parent-style-name=\"standard\">\n");
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh outs.printf(" draw:fill-color=\"%s\" ", s.fillColor.c_str());
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh outs.printf(" draw:fill-opacity=\"%s\" ", s.fillOpacity.c_str());
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh outs.printf(" draw:stroke=\"%s\" ", s.stroke.c_str());
17d87f5698f5c2958d38c6a6207c7b322a7adaf9johanengelen outs.printf(" svg:stroke-width=\"%s\" ", s.strokeWidth.c_str());
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh outs.printf(" svg:stroke-color=\"%s\" ", s.strokeColor.c_str());
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh outs.printf(" svg:stroke-opacity=\"%s\" ", s.strokeOpacity.c_str());
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh //## Dump our gradient table
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("<!-- ####### Gradients from Inkscape document ####### -->\n");
e454b92b3d16b0909892cddef064b745898c924dJon A. Cruz for (giter = gradientTable.begin() ; giter != gradientTable.end() ; giter++)
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh ===================================================================
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh LINEAR gradient. We need something that looks like this:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh <draw:gradient draw:name="Gradient_20_7"
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh draw:display-name="Gradient 7"
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh draw:style="linear"
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh draw:start-color="#008080" draw:end-color="#993366"
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh draw:start-intensity="100%" draw:end-intensity="100%"
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh draw:angle="150" draw:border="0%"/>
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh ===================================================================
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh g_warning("Need at least 2 tops for a linear gradient");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("draw:name=\"%#s_g\"\n", gi.name.c_str());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" draw:display-name=\"imported linear %d\"\n",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" svg:x1=\"%05.3fcm\" svg:y1=\"%05.3fcm\"\n",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" svg:x2=\"%05.3fcm\" svg:y2=\"%05.3fcm\"\n",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" svg:gradientUnits=\"objectBoundingBox\">\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh ===================================================================
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh RADIAL gradient. We need something that looks like this:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh <!-- radial gradient, light gray to white, centered, 0% border -->
17d87f5698f5c2958d38c6a6207c7b322a7adaf9johanengelen <draw:gradient draw:name="radial_20_borderless"
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh draw:display-name="radial borderless"
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh draw:style="radial"
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh draw:cx="50%" draw:cy="50%"
17d87f5698f5c2958d38c6a6207c7b322a7adaf9johanengelen draw:start-color="#999999" draw:end-color="#ffffff"
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh draw:border="0%"/>
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh ===================================================================
e454b92b3d16b0909892cddef064b745898c924dJon A. Cruz g_warning("Need at least 2 tops for a radial gradient");
e454b92b3d16b0909892cddef064b745898c924dJon A. Cruz outs.printf("draw:name=\"%#s_g\"\n", gi.name.c_str());
e454b92b3d16b0909892cddef064b745898c924dJon A. Cruz outs.printf(" draw:display-name=\"imported radial %d\"\n",
e454b92b3d16b0909892cddef064b745898c924dJon A. Cruz outs.printf(" svg:cx=\"%05.3f\" svg:cy=\"%05.3f\"\n",
e454b92b3d16b0909892cddef064b745898c924dJon A. Cruz outs.printf(" svg:fx=\"%05.3f\" svg:fy=\"%05.3f\"\n",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" svg:gradientUnits=\"objectBoundingBox\">\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh g_warning("unsupported gradient style '%s'", gi.style.c_str());
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh outs.printf("<style:style style:name=\"%#s\" style:family=\"graphic\" ",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("style:parent-style-name=\"standard\">\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <style:graphic-properties draw:fill=\"gradient\" ");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" draw:textarea-horizontal-align=\"center\" ");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("draw:textarea-vertical-align=\"middle\"/>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <draw:layer draw:name=\"layout\"/>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <draw:layer draw:name=\"background\"/>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <draw:layer draw:name=\"backgroundobjects\"/>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <draw:layer draw:name=\"controls\"/>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" <draw:layer draw:name=\"measurelines\"/>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("<style:master-page style:name=\"Default\"\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" style:page-master-name=\"PM1\" draw:style-name=\"dp1\"/>\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("*************************************************************************\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("*************************************************************************\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //Make our entry
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh ZipEntry *ze = zf.newEntry("styles.xml", "ODF style file");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh return true;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh * Writes an SVG path as an ODF <draw:path>
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh bool closed = false;
3711b3e25395437ee0a09dbbb2a76d999c4ef322mikloshbool OdfOutput::processStyle(Writer &outs, SPItem *item,
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh guint32 fillCol = style->fill.value.color.toRGBA32( 0 );
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //g_message("## %s %lx", id.c_str(), (unsigned int)fillCol);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //## STROKE
dc7a7dae1757af28215a38f4b71ef84776b38f6cJosh Andler guint32 strokeCol = style->stroke.value.color.toRGBA32( 0 );
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh snprintf(buf, 15, "%.3fpt", style->stroke_width.value);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //Look for existing identical style;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh bool styleMatch = false;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (iter=styleTable.begin() ; iter!=styleTable.end() ; iter++)
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //map to existing styleTable entry
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //g_message("found duplicate style:%s", styleName.c_str());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //## Dont need a new style
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh return false;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh snprintf(buf, 15, "style%d", (int)styleTable.size());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf("<style:style style:name=\"%s\"", si.name.c_str());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" style:family=\"graphic\" style:parent-style-name=\"standard\">\n");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" draw:fill-color=\"%s\" ", si.fillColor.c_str());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" draw:fill-opacity=\"%s\" ", si.fillOpacity.c_str());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" draw:stroke=\"%s\" ", si.stroke.c_str());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" svg:stroke-width=\"%s\" ", si.strokeWidth.c_str());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" svg:stroke-color=\"%s\" ", si.strokeColor.c_str());
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh outs.printf(" svg:stroke-opacity=\"%s\" ", si.strokeOpacity.c_str());
ed09b99cb3592f9afb57d2ae3fb88e7f1aca0eb4miklosh return true;
3711b3e25395437ee0a09dbbb2a76d999c4ef322mikloshbool OdfOutput::processGradient(Writer &outs, SPItem *item,
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh return false;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh return false;
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh return false;
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh //## Gradient. Look in writeStyle() below to see what info
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh // we need to read into GradientInfo.
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh return false;
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh SPGradient *gradient = SP_GRADIENT(SP_STYLE_FILL_SERVER(style));
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh SPGradient *grvec = sp_gradient_get_vector(gradient, FALSE);
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh SPLinearGradient *linGrad = SP_LINEARGRADIENT(gradient);
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh NR::Point p1(linGrad->x1.value, linGrad->y1.value);
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh p1 = p1 * tf;
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh gi.x1 = p1[NR::X];
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh gi.y1 = p1[NR::Y];
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh NR::Point p2(linGrad->x2.value, linGrad->y2.value);
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh p2 = p2 * tf;
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh gi.x2 = p2[NR::X];
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh gi.y2 = p2[NR::Y];
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh SPRadialGradient *radGrad = SP_RADIALGRADIENT(gradient);
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh gi.cx = radGrad->cx.computed * 100.0;//ODG cx is percentages
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh return false;
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh //Look for existing identical style;
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh bool gradientMatch = false;
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh for (iter=gradientTable.begin() ; iter!=gradientTable.end() ; iter++)
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh //map to existing gradientTable entry
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh //g_message("found duplicate style:%s", gradientName.c_str());
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh return true;
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh //## No match, let us write a new entry
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh snprintf(buf, 15, "gradient%d", (int)gradientTable.size());
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh ===================================================================
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh LINEAR gradient. We need something that looks like this:
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh <draw:gradient draw:name="Gradient_20_7"
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh draw:display-name="Gradient 7"
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh draw:style="linear"
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh draw:start-color="#008080" draw:end-color="#993366"
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh draw:start-intensity="100%" draw:end-intensity="100%"
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh draw:angle="150" draw:border="0%"/>
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh ===================================================================
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh g_warning("Need at least 2 stops for a linear gradient");
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh return false;;
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh outs.printf("draw:name=\"%#s_g\"\n", gi.name.c_str());
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh outs.printf(" draw:display-name=\"imported linear %d\"\n",
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh outs.printf(" svg:gradientUnits=\"objectBoundingBox\"\n");
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh outs.printf(" svg:x1=\"%05.3fcm\" svg:y1=\"%05.3fcm\"\n",
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh outs.printf(" svg:x2=\"%05.3fcm\" svg:y2=\"%05.3fcm\">\n",
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh ===================================================================
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh RADIAL gradient. We need something that looks like this:
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh <!-- radial gradient, light gray to white, centered, 0% border -->
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh <draw:gradient draw:name="radial_20_borderless"
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh draw:display-name="radial borderless"
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh draw:style="radial"
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh draw:cx="50%" draw:cy="50%"
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh draw:start-color="#999999" draw:end-color="#ffffff"
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh draw:border="0%"/>
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh ===================================================================
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh g_warning("Need at least 2 stops for a radial gradient");
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh return false;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh outs.printf("draw:name=\"%#s_g\"\n", gi.name.c_str());
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh outs.printf(" draw:display-name=\"imported radial %d\"\n",
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh outs.printf(" svg:gradientUnits=\"objectBoundingBox\"\n");
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh outs.printf(" svg:cx=\"%05.3f\" svg:cy=\"%05.3f\"\n",
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh outs.printf(" svg:fx=\"%05.3f\" svg:fy=\"%05.3f\"\n",
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh g_warning("unsupported gradient style '%s'", gi.style.c_str());
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh return false;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh outs.printf("<style:style style:name=\"%#s\" style:family=\"graphic\" ",
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh outs.printf("style:parent-style-name=\"standard\">\n");
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh outs.printf(" <style:graphic-properties draw:fill=\"gradient\" ");
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh outs.printf(" draw:textarea-horizontal-align=\"center\" ");
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh outs.printf("draw:textarea-vertical-align=\"middle\"/>\n");
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh return true;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh * SECOND PASS.
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh * This is the main SPObject tree output to ODF. preprocess()
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh * must be called prior to this, as elements will often reference
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh * data parsed and tabled in preprocess().
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emikloshbool OdfOutput::writeTree(Writer &couts, Writer &souts,
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh //# Get the SPItem, if applicable
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh SPObject *reprobj = SP_ACTIVE_DOCUMENT->getObjectByRepr(node);
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh return true;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh return true;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh //### Get SVG-to-ODF transform
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh //### Get ODF bounding box params for item
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh return true;
double rotate;
double xskew;
double yskew;
double xscale;
double yscale;
//g_message("##### %s #####", nodeName.c_str());
//g_message("### %s is a shape", nodeName.c_str());
if (curve)
* Write the header for the content.xml file
* Write the footer for the style.xml file
outs.printf("<style:style style:name=\"gr1\" style:family=\"graphic\" style:parent-style-name=\"standard\">\n");
outs.printf(" draw:luminance=\"0%%\" draw:contrast=\"0%%\" draw:gamma=\"100%%\" draw:red=\"0%%\"\n");
* Write the header for the content.xml file
* Write the footer for the content.xml file
* Write the content.xml file. Writes the namesspace headers, then
//Content.xml stream
//Style.xml stream
reset();
"<mimetype>text/x-povray-script</mimetype>\n"
new OdfOutput());
return TRUE;