Commit 5059ec0d35547c0b3328c3089221b7cb3c3ac45d
1 parent
daeb5a85
Add Matrix class under QPDFObjectHandle
Showing
6 changed files
with
124 additions
and
0 deletions
ChangeLog
| 1 | +2018-12-31 Jay Berkenbilt <ejb@ql.org> | ||
| 2 | + | ||
| 3 | + * Add QPDFObjectHandle::Matrix, similar to | ||
| 4 | + QPDFObjectHandle::Rectangle, as a convenience class for | ||
| 5 | + six-element arrays that are used as matrices. | ||
| 6 | + | ||
| 1 | 2018-12-23 Jay Berkenbilt <ejb@ql.org> | 7 | 2018-12-23 Jay Berkenbilt <ejb@ql.org> |
| 2 | 8 | ||
| 3 | * When specifying @arg on the command line, if the file "arg" does | 9 | * When specifying @arg on the command line, if the file "arg" does |
include/qpdf/QPDFObjectHandle.hh
| @@ -198,6 +198,38 @@ class QPDFObjectHandle | @@ -198,6 +198,38 @@ class QPDFObjectHandle | ||
| 198 | double ury; | 198 | double ury; |
| 199 | }; | 199 | }; |
| 200 | 200 | ||
| 201 | + // Convenience object for transformation matrices | ||
| 202 | + class Matrix | ||
| 203 | + { | ||
| 204 | + public: | ||
| 205 | + Matrix() : | ||
| 206 | + a(0.0), | ||
| 207 | + b(0.0), | ||
| 208 | + c(0.0), | ||
| 209 | + d(0.0), | ||
| 210 | + e(0.0), | ||
| 211 | + f(0.0) | ||
| 212 | + { | ||
| 213 | + } | ||
| 214 | + Matrix(double a, double b, double c, | ||
| 215 | + double d, double e, double f) : | ||
| 216 | + a(a), | ||
| 217 | + b(b), | ||
| 218 | + c(c), | ||
| 219 | + d(d), | ||
| 220 | + e(e), | ||
| 221 | + f(f) | ||
| 222 | + { | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + double a; | ||
| 226 | + double b; | ||
| 227 | + double c; | ||
| 228 | + double d; | ||
| 229 | + double e; | ||
| 230 | + double f; | ||
| 231 | + }; | ||
| 232 | + | ||
| 201 | QPDF_DLL | 233 | QPDF_DLL |
| 202 | QPDFObjectHandle(); | 234 | QPDFObjectHandle(); |
| 203 | QPDF_DLL | 235 | QPDF_DLL |
| @@ -368,6 +400,8 @@ class QPDFObjectHandle | @@ -368,6 +400,8 @@ class QPDFObjectHandle | ||
| 368 | QPDF_DLL | 400 | QPDF_DLL |
| 369 | static QPDFObjectHandle newArray(Rectangle const&); | 401 | static QPDFObjectHandle newArray(Rectangle const&); |
| 370 | QPDF_DLL | 402 | QPDF_DLL |
| 403 | + static QPDFObjectHandle newArray(Matrix const&); | ||
| 404 | + QPDF_DLL | ||
| 371 | static QPDFObjectHandle newDictionary(); | 405 | static QPDFObjectHandle newDictionary(); |
| 372 | QPDF_DLL | 406 | QPDF_DLL |
| 373 | static QPDFObjectHandle newDictionary( | 407 | static QPDFObjectHandle newDictionary( |
| @@ -377,6 +411,10 @@ class QPDFObjectHandle | @@ -377,6 +411,10 @@ class QPDFObjectHandle | ||
| 377 | // form of newArray. | 411 | // form of newArray. |
| 378 | QPDF_DLL | 412 | QPDF_DLL |
| 379 | static QPDFObjectHandle newFromRectangle(Rectangle const&); | 413 | static QPDFObjectHandle newFromRectangle(Rectangle const&); |
| 414 | + // Create an array from a matrix. Equivalent to the matrix | ||
| 415 | + // form of newArray. | ||
| 416 | + QPDF_DLL | ||
| 417 | + static QPDFObjectHandle newFromMatrix(Matrix const&); | ||
| 380 | 418 | ||
| 381 | // Create a new stream and associate it with the given qpdf | 419 | // Create a new stream and associate it with the given qpdf |
| 382 | // object. A subsequent call must be made to replaceStreamData() | 420 | // object. A subsequent call must be made to replaceStreamData() |
| @@ -500,6 +538,12 @@ class QPDFObjectHandle | @@ -500,6 +538,12 @@ class QPDFObjectHandle | ||
| 500 | // rectangle. Otherwise, return the rectangle [0, 0, 0, 0] | 538 | // rectangle. Otherwise, return the rectangle [0, 0, 0, 0] |
| 501 | QPDF_DLL | 539 | QPDF_DLL |
| 502 | Rectangle getArrayAsRectangle(); | 540 | Rectangle getArrayAsRectangle(); |
| 541 | + QPDF_DLL | ||
| 542 | + bool isMatrix(); | ||
| 543 | + // If the array an array of six numeric values, return as a | ||
| 544 | + // matrix. Otherwise, return the matrix [1, 0, 0, 1, 0, 0] | ||
| 545 | + QPDF_DLL | ||
| 546 | + Matrix getArrayAsMatrix(); | ||
| 503 | 547 | ||
| 504 | // Methods for dictionary objects | 548 | // Methods for dictionary objects |
| 505 | QPDF_DLL | 549 | QPDF_DLL |
libqpdf/QPDFMatrix.cc
| @@ -22,6 +22,17 @@ QPDFMatrix::QPDFMatrix(double a, double b, double c, | @@ -22,6 +22,17 @@ QPDFMatrix::QPDFMatrix(double a, double b, double c, | ||
| 22 | { | 22 | { |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | +QPDFMatrix::QPDFMatrix(QPDFObjectHandle::Matrix const& m) : | ||
| 26 | + a(m.a), | ||
| 27 | + b(m.b), | ||
| 28 | + c(m.c), | ||
| 29 | + d(m.d), | ||
| 30 | + e(m.e), | ||
| 31 | + f(m.f) | ||
| 32 | +{ | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | + | ||
| 25 | std::string | 36 | std::string |
| 26 | QPDFMatrix::unparse() const | 37 | QPDFMatrix::unparse() const |
| 27 | { | 38 | { |
libqpdf/QPDFObjectHandle.cc
| @@ -575,6 +575,26 @@ QPDFObjectHandle::isRectangle() | @@ -575,6 +575,26 @@ QPDFObjectHandle::isRectangle() | ||
| 575 | return true; | 575 | return true; |
| 576 | } | 576 | } |
| 577 | 577 | ||
| 578 | +bool | ||
| 579 | +QPDFObjectHandle::isMatrix() | ||
| 580 | +{ | ||
| 581 | + if (! isArray()) | ||
| 582 | + { | ||
| 583 | + return false; | ||
| 584 | + } | ||
| 585 | + if (getArrayNItems() != 6) | ||
| 586 | + { | ||
| 587 | + return false; | ||
| 588 | + } | ||
| 589 | + for (size_t i = 0; i < 6; ++i) | ||
| 590 | + { | ||
| 591 | + if (! getArrayItem(i).isNumber()) | ||
| 592 | + { | ||
| 593 | + return false; | ||
| 594 | + } | ||
| 595 | + } | ||
| 596 | + return true; | ||
| 597 | +} | ||
| 578 | 598 | ||
| 579 | QPDFObjectHandle::Rectangle | 599 | QPDFObjectHandle::Rectangle |
| 580 | QPDFObjectHandle::getArrayAsRectangle() | 600 | QPDFObjectHandle::getArrayAsRectangle() |
| @@ -590,6 +610,22 @@ QPDFObjectHandle::getArrayAsRectangle() | @@ -590,6 +610,22 @@ QPDFObjectHandle::getArrayAsRectangle() | ||
| 590 | return result; | 610 | return result; |
| 591 | } | 611 | } |
| 592 | 612 | ||
| 613 | +QPDFObjectHandle::Matrix | ||
| 614 | +QPDFObjectHandle::getArrayAsMatrix() | ||
| 615 | +{ | ||
| 616 | + Matrix result; | ||
| 617 | + if (isMatrix()) | ||
| 618 | + { | ||
| 619 | + result = Matrix(getArrayItem(0).getNumericValue(), | ||
| 620 | + getArrayItem(1).getNumericValue(), | ||
| 621 | + getArrayItem(2).getNumericValue(), | ||
| 622 | + getArrayItem(3).getNumericValue(), | ||
| 623 | + getArrayItem(4).getNumericValue(), | ||
| 624 | + getArrayItem(5).getNumericValue()); | ||
| 625 | + } | ||
| 626 | + return result; | ||
| 627 | +} | ||
| 628 | + | ||
| 593 | std::vector<QPDFObjectHandle> | 629 | std::vector<QPDFObjectHandle> |
| 594 | QPDFObjectHandle::getArrayAsVector() | 630 | QPDFObjectHandle::getArrayAsVector() |
| 595 | { | 631 | { |
| @@ -1931,12 +1967,31 @@ QPDFObjectHandle::newArray(Rectangle const& rect) | @@ -1931,12 +1967,31 @@ QPDFObjectHandle::newArray(Rectangle const& rect) | ||
| 1931 | } | 1967 | } |
| 1932 | 1968 | ||
| 1933 | QPDFObjectHandle | 1969 | QPDFObjectHandle |
| 1970 | +QPDFObjectHandle::newArray(Matrix const& matrix) | ||
| 1971 | +{ | ||
| 1972 | + std::vector<QPDFObjectHandle> items; | ||
| 1973 | + items.push_back(newReal(matrix.a)); | ||
| 1974 | + items.push_back(newReal(matrix.b)); | ||
| 1975 | + items.push_back(newReal(matrix.c)); | ||
| 1976 | + items.push_back(newReal(matrix.d)); | ||
| 1977 | + items.push_back(newReal(matrix.e)); | ||
| 1978 | + items.push_back(newReal(matrix.f)); | ||
| 1979 | + return newArray(items); | ||
| 1980 | +} | ||
| 1981 | + | ||
| 1982 | +QPDFObjectHandle | ||
| 1934 | QPDFObjectHandle::newFromRectangle(Rectangle const& rect) | 1983 | QPDFObjectHandle::newFromRectangle(Rectangle const& rect) |
| 1935 | { | 1984 | { |
| 1936 | return newArray(rect); | 1985 | return newArray(rect); |
| 1937 | } | 1986 | } |
| 1938 | 1987 | ||
| 1939 | QPDFObjectHandle | 1988 | QPDFObjectHandle |
| 1989 | +QPDFObjectHandle::newFromMatrix(Matrix const& rect) | ||
| 1990 | +{ | ||
| 1991 | + return newArray(rect); | ||
| 1992 | +} | ||
| 1993 | + | ||
| 1994 | +QPDFObjectHandle | ||
| 1940 | QPDFObjectHandle::newDictionary() | 1995 | QPDFObjectHandle::newDictionary() |
| 1941 | { | 1996 | { |
| 1942 | return newDictionary(std::map<std::string, QPDFObjectHandle>()); | 1997 | return newDictionary(std::map<std::string, QPDFObjectHandle>()); |
libqpdf/qpdf/QPDFMatrix.hh
| 1 | #ifndef QPDFMATRIX_HH | 1 | #ifndef QPDFMATRIX_HH |
| 2 | #define QPDFMATRIX_HH | 2 | #define QPDFMATRIX_HH |
| 3 | 3 | ||
| 4 | +#include <qpdf/QPDFObjectHandle.hh> | ||
| 4 | #include <qpdf/DLL.h> | 5 | #include <qpdf/DLL.h> |
| 5 | #include <string> | 6 | #include <string> |
| 6 | 7 | ||
| @@ -12,6 +13,8 @@ class QPDFMatrix | @@ -12,6 +13,8 @@ class QPDFMatrix | ||
| 12 | QPDF_DLL | 13 | QPDF_DLL |
| 13 | QPDFMatrix(double a, double b, double c, | 14 | QPDFMatrix(double a, double b, double c, |
| 14 | double d, double e, double f); | 15 | double d, double e, double f); |
| 16 | + QPDF_DLL | ||
| 17 | + QPDFMatrix(QPDFObjectHandle::Matrix const&); | ||
| 15 | 18 | ||
| 16 | QPDF_DLL | 19 | QPDF_DLL |
| 17 | std::string unparse() const; | 20 | std::string unparse() const; |
libtests/matrix.cc
| @@ -50,6 +50,11 @@ int main() | @@ -50,6 +50,11 @@ int main() | ||
| 50 | m.transform(240, 480, xp, yp); | 50 | m.transform(240, 480, xp, yp); |
| 51 | check_xy(xp, yp, "2582.50 4912.00"); | 51 | check_xy(xp, yp, "2582.50 4912.00"); |
| 52 | 52 | ||
| 53 | + check(QPDFMatrix( | ||
| 54 | + QPDFObjectHandle::parse( | ||
| 55 | + "[3 1 4 1 5 9.26535]").getArrayAsMatrix()), | ||
| 56 | + "3.00000 1.00000 4.00000 1.00000 5.00000 9.26535"); | ||
| 57 | + | ||
| 53 | std::cout << "matrix tests done" << std::endl; | 58 | std::cout << "matrix tests done" << std::endl; |
| 54 | return 0; | 59 | return 0; |
| 55 | } | 60 | } |