Commit daeb5a85b6ded478aaac942c439ef5fd6bb8874f

Authored by Jay Berkenbilt
1 parent 3440ea7d

Transformation matrix

libqpdf/QPDFMatrix.cc 0 → 100644
  1 +#include <qpdf/QPDFMatrix.hh>
  2 +#include <qpdf/QUtil.hh>
  3 +
  4 +QPDFMatrix::QPDFMatrix() :
  5 + a(1.0),
  6 + b(0.0),
  7 + c(0.0),
  8 + d(1.0),
  9 + e(0.0),
  10 + f(0.0)
  11 +{
  12 +}
  13 +
  14 +QPDFMatrix::QPDFMatrix(double a, double b, double c,
  15 + double d, double e, double f) :
  16 + a(a),
  17 + b(b),
  18 + c(c),
  19 + d(d),
  20 + e(e),
  21 + f(f)
  22 +{
  23 +}
  24 +
  25 +std::string
  26 +QPDFMatrix::unparse() const
  27 +{
  28 + return (QUtil::double_to_string(a, 5) + " " +
  29 + QUtil::double_to_string(b, 5) + " " +
  30 + QUtil::double_to_string(c, 5) + " " +
  31 + QUtil::double_to_string(d, 5) + " " +
  32 + QUtil::double_to_string(e, 5) + " " +
  33 + QUtil::double_to_string(f, 5));
  34 +}
  35 +
  36 +void
  37 +QPDFMatrix::concat(QPDFMatrix const& other)
  38 +{
  39 + double ap = (this->a * other.a) + (this->c * other.b);
  40 + double bp = (this->b * other.a) + (this->d * other.b);
  41 + double cp = (this->a * other.c) + (this->c * other.d);
  42 + double dp = (this->b * other.c) + (this->d * other.d);
  43 + double ep = (this->a * other.e) + (this->c * other.f) + this->e;
  44 + double fp = (this->b * other.e) + (this->d * other.f) + this->f;
  45 + this-> a = ap;
  46 + this-> b = bp;
  47 + this-> c = cp;
  48 + this-> d = dp;
  49 + this-> e = ep;
  50 + this-> f = fp;
  51 +}
  52 +
  53 +void
  54 +QPDFMatrix::scale(double sx, double sy)
  55 +{
  56 + concat(QPDFMatrix(sx, 0, 0, sy, 0, 0));
  57 +}
  58 +
  59 +void
  60 +QPDFMatrix::translate(double tx, double ty)
  61 +{
  62 + concat(QPDFMatrix(1, 0, 0, 1, tx, ty));
  63 +}
  64 +
  65 +void
  66 +QPDFMatrix::rotatex90(int angle)
  67 +{
  68 + switch (angle)
  69 + {
  70 + case 90:
  71 + concat(QPDFMatrix(0, 1, -1, 0, 0, 0));
  72 + break;
  73 + case 180:
  74 + concat(QPDFMatrix(-1, 0, 0, -1, 0, 0));
  75 + break;
  76 + case 270:
  77 + concat(QPDFMatrix(0, -1, 1, 0, 0, 0));
  78 + break;
  79 + default:
  80 + // ignore
  81 + break;
  82 + }
  83 +}
  84 +
  85 +void
  86 +QPDFMatrix::transform(double x, double y, double& xp, double& yp)
  87 +{
  88 + xp = (this->a * x) + (this->c * y) + this->e;
  89 + yp = (this->b * x) + (this->d * y) + this->f;
  90 +}
libqpdf/build.mk
@@ -41,6 +41,7 @@ SRCS_libqpdf = \ @@ -41,6 +41,7 @@ SRCS_libqpdf = \
41 libqpdf/QPDFAnnotationObjectHelper.cc \ 41 libqpdf/QPDFAnnotationObjectHelper.cc \
42 libqpdf/QPDFExc.cc \ 42 libqpdf/QPDFExc.cc \
43 libqpdf/QPDFFormFieldObjectHelper.cc \ 43 libqpdf/QPDFFormFieldObjectHelper.cc \
  44 + libqpdf/QPDFMatrix.cc \
44 libqpdf/QPDFNameTreeObjectHelper.cc \ 45 libqpdf/QPDFNameTreeObjectHelper.cc \
45 libqpdf/QPDFNumberTreeObjectHelper.cc \ 46 libqpdf/QPDFNumberTreeObjectHelper.cc \
46 libqpdf/QPDFObjGen.cc \ 47 libqpdf/QPDFObjGen.cc \
libqpdf/qpdf/QPDFMatrix.hh 0 → 100644
  1 +#ifndef QPDFMATRIX_HH
  2 +#define QPDFMATRIX_HH
  3 +
  4 +#include <qpdf/DLL.h>
  5 +#include <string>
  6 +
  7 +class QPDFMatrix
  8 +{
  9 + public:
  10 + QPDF_DLL
  11 + QPDFMatrix();
  12 + QPDF_DLL
  13 + QPDFMatrix(double a, double b, double c,
  14 + double d, double e, double f);
  15 +
  16 + QPDF_DLL
  17 + std::string unparse() const;
  18 +
  19 + // This is not part of the public API. Just provide the methods we
  20 + // need as we need them.
  21 + QPDF_DLL
  22 + void concat(QPDFMatrix const& other);
  23 + QPDF_DLL
  24 + void scale(double sx, double sy);
  25 + QPDF_DLL
  26 + void translate(double tx, double ty);
  27 + // Any value other than 90, 180, or 270 is ignored
  28 + QPDF_DLL
  29 + void rotatex90(int angle);
  30 +
  31 + QPDF_DLL
  32 + void transform(double x, double y, double& xp, double& yp);
  33 +
  34 + private:
  35 + double a;
  36 + double b;
  37 + double c;
  38 + double d;
  39 + double e;
  40 + double f;
  41 +};
  42 +
  43 +#endif // QPDFMATRIX_HH
libtests/build.mk
@@ -12,6 +12,7 @@ BINS_libtests = \ @@ -12,6 +12,7 @@ BINS_libtests = \
12 input_source \ 12 input_source \
13 json \ 13 json \
14 lzw \ 14 lzw \
  15 + matrix \
15 md5 \ 16 md5 \
16 numrange \ 17 numrange \
17 pointer_holder \ 18 pointer_holder \
libtests/matrix.cc 0 → 100644
  1 +#include <qpdf/QPDFMatrix.hh>
  2 +#include <qpdf/QUtil.hh>
  3 +#include <assert.h>
  4 +#include <iostream>
  5 +
  6 +static void check(QPDFMatrix const& m, std::string const& exp)
  7 +{
  8 + std::string u = m.unparse();
  9 + if (u != exp)
  10 + {
  11 + std::cout << "got " << u << ", wanted " << exp << std::endl;
  12 + }
  13 +}
  14 +
  15 +static void check_xy(double x, double y, std::string const& exp)
  16 +{
  17 + std::string u = (QUtil::double_to_string(x, 2) + " " +
  18 + QUtil::double_to_string(y, 2));
  19 + if (u != exp)
  20 + {
  21 + std::cout << "got " << u << ", wanted " << exp << std::endl;
  22 + }
  23 +}
  24 +
  25 +int main()
  26 +{
  27 + QPDFMatrix m;
  28 + check(m, "1.00000 0.00000 0.00000 1.00000 0.00000 0.00000");
  29 + m.translate(10, 20);
  30 + check(m, "1.00000 0.00000 0.00000 1.00000 10.00000 20.00000");
  31 + m.scale(1.5, 2);
  32 + check(m, "1.50000 0.00000 0.00000 2.00000 10.00000 20.00000");
  33 + m.translate(30, 40);
  34 + check(m, "1.50000 0.00000 0.00000 2.00000 55.00000 100.00000");
  35 + m.concat(QPDFMatrix(1, 2, 3, 4, 5, 6));
  36 + check(m, "1.50000 4.00000 4.50000 8.00000 62.50000 112.00000");
  37 + m.rotatex90(90);
  38 + check(m, "4.50000 8.00000 -1.50000 -4.00000 62.50000 112.00000");
  39 + m.rotatex90(180);
  40 + check(m, "-4.50000 -8.00000 1.50000 4.00000 62.50000 112.00000");
  41 + m.rotatex90(270);
  42 + check(m, "-1.50000 -4.00000 -4.50000 -8.00000 62.50000 112.00000");
  43 + m.rotatex90(180);
  44 + check(m, "1.50000 4.00000 4.50000 8.00000 62.50000 112.00000");
  45 + m.rotatex90(12345);
  46 + check(m, "1.50000 4.00000 4.50000 8.00000 62.50000 112.00000");
  47 +
  48 + double xp = 0;
  49 + double yp = 0;
  50 + m.transform(240, 480, xp, yp);
  51 + check_xy(xp, yp, "2582.50 4912.00");
  52 +
  53 + std::cout << "matrix tests done" << std::endl;
  54 + return 0;
  55 +}