diff --git a/ChangeLog b/ChangeLog index 1426a50f..b7109173 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2018-12-31 Jay Berkenbilt + + * Add QPDFObjectHandle::Matrix, similar to + QPDFObjectHandle::Rectangle, as a convenience class for + six-element arrays that are used as matrices. + 2018-12-23 Jay Berkenbilt * When specifying @arg on the command line, if the file "arg" does diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index 9cc67686..a4b469c2 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -198,6 +198,38 @@ class QPDFObjectHandle double ury; }; + // Convenience object for transformation matrices + class Matrix + { + public: + Matrix() : + a(0.0), + b(0.0), + c(0.0), + d(0.0), + e(0.0), + f(0.0) + { + } + Matrix(double a, double b, double c, + double d, double e, double f) : + a(a), + b(b), + c(c), + d(d), + e(e), + f(f) + { + } + + double a; + double b; + double c; + double d; + double e; + double f; + }; + QPDF_DLL QPDFObjectHandle(); QPDF_DLL @@ -368,6 +400,8 @@ class QPDFObjectHandle QPDF_DLL static QPDFObjectHandle newArray(Rectangle const&); QPDF_DLL + static QPDFObjectHandle newArray(Matrix const&); + QPDF_DLL static QPDFObjectHandle newDictionary(); QPDF_DLL static QPDFObjectHandle newDictionary( @@ -377,6 +411,10 @@ class QPDFObjectHandle // form of newArray. QPDF_DLL static QPDFObjectHandle newFromRectangle(Rectangle const&); + // Create an array from a matrix. Equivalent to the matrix + // form of newArray. + QPDF_DLL + static QPDFObjectHandle newFromMatrix(Matrix const&); // Create a new stream and associate it with the given qpdf // object. A subsequent call must be made to replaceStreamData() @@ -500,6 +538,12 @@ class QPDFObjectHandle // rectangle. Otherwise, return the rectangle [0, 0, 0, 0] QPDF_DLL Rectangle getArrayAsRectangle(); + QPDF_DLL + bool isMatrix(); + // If the array an array of six numeric values, return as a + // matrix. Otherwise, return the matrix [1, 0, 0, 1, 0, 0] + QPDF_DLL + Matrix getArrayAsMatrix(); // Methods for dictionary objects QPDF_DLL diff --git a/libqpdf/QPDFMatrix.cc b/libqpdf/QPDFMatrix.cc index 28a338f0..3d410435 100644 --- a/libqpdf/QPDFMatrix.cc +++ b/libqpdf/QPDFMatrix.cc @@ -22,6 +22,17 @@ QPDFMatrix::QPDFMatrix(double a, double b, double c, { } +QPDFMatrix::QPDFMatrix(QPDFObjectHandle::Matrix const& m) : + a(m.a), + b(m.b), + c(m.c), + d(m.d), + e(m.e), + f(m.f) +{ +} + + std::string QPDFMatrix::unparse() const { diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index d0373d63..51df113c 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -575,6 +575,26 @@ QPDFObjectHandle::isRectangle() return true; } +bool +QPDFObjectHandle::isMatrix() +{ + if (! isArray()) + { + return false; + } + if (getArrayNItems() != 6) + { + return false; + } + for (size_t i = 0; i < 6; ++i) + { + if (! getArrayItem(i).isNumber()) + { + return false; + } + } + return true; +} QPDFObjectHandle::Rectangle QPDFObjectHandle::getArrayAsRectangle() @@ -590,6 +610,22 @@ QPDFObjectHandle::getArrayAsRectangle() return result; } +QPDFObjectHandle::Matrix +QPDFObjectHandle::getArrayAsMatrix() +{ + Matrix result; + if (isMatrix()) + { + result = Matrix(getArrayItem(0).getNumericValue(), + getArrayItem(1).getNumericValue(), + getArrayItem(2).getNumericValue(), + getArrayItem(3).getNumericValue(), + getArrayItem(4).getNumericValue(), + getArrayItem(5).getNumericValue()); + } + return result; +} + std::vector QPDFObjectHandle::getArrayAsVector() { @@ -1930,12 +1966,31 @@ QPDFObjectHandle::newArray(Rectangle const& rect) return newArray(items); } +QPDFObjectHandle +QPDFObjectHandle::newArray(Matrix const& matrix) +{ + std::vector items; + items.push_back(newReal(matrix.a)); + items.push_back(newReal(matrix.b)); + items.push_back(newReal(matrix.c)); + items.push_back(newReal(matrix.d)); + items.push_back(newReal(matrix.e)); + items.push_back(newReal(matrix.f)); + return newArray(items); +} + QPDFObjectHandle QPDFObjectHandle::newFromRectangle(Rectangle const& rect) { return newArray(rect); } +QPDFObjectHandle +QPDFObjectHandle::newFromMatrix(Matrix const& rect) +{ + return newArray(rect); +} + QPDFObjectHandle QPDFObjectHandle::newDictionary() { diff --git a/libqpdf/qpdf/QPDFMatrix.hh b/libqpdf/qpdf/QPDFMatrix.hh index dcf8b195..81bc51f1 100644 --- a/libqpdf/qpdf/QPDFMatrix.hh +++ b/libqpdf/qpdf/QPDFMatrix.hh @@ -1,6 +1,7 @@ #ifndef QPDFMATRIX_HH #define QPDFMATRIX_HH +#include #include #include @@ -12,6 +13,8 @@ class QPDFMatrix QPDF_DLL QPDFMatrix(double a, double b, double c, double d, double e, double f); + QPDF_DLL + QPDFMatrix(QPDFObjectHandle::Matrix const&); QPDF_DLL std::string unparse() const; diff --git a/libtests/matrix.cc b/libtests/matrix.cc index d27e96cf..f022ce4e 100644 --- a/libtests/matrix.cc +++ b/libtests/matrix.cc @@ -50,6 +50,11 @@ int main() m.transform(240, 480, xp, yp); check_xy(xp, yp, "2582.50 4912.00"); + check(QPDFMatrix( + QPDFObjectHandle::parse( + "[3 1 4 1 5 9.26535]").getArrayAsMatrix()), + "3.00000 1.00000 4.00000 1.00000 5.00000 9.26535"); + std::cout << "matrix tests done" << std::endl; return 0; }