]> mj.ucw.cz Git - paperjam.git/blobdiff - pdf-tools.cc
Top and bottom margins were swapped
[paperjam.git] / pdf-tools.cc
index c170d8ae9a3b0fc2dfbddadfb249ca59d9c77ab0..6a0b9b6e01db0d82a594f3e51cae8a51a45ca212 100644 (file)
@@ -4,69 +4,16 @@
  *     (c) 2018 Martin Mares <mj@ucw.cz>
  */
 
-#include <cstdarg>
 #include <cstdio>
 #include <cstdlib>
 
 #include <iconv.h>
 
-using namespace std;
-
-#include "pdf-tools.h"
+#include "jam.h"
 
 #include <qpdf/QUtil.hh>
 #include <qpdf/Pl_Concatenate.hh>
 
-/*** Messages ***/
-
-int debug_mode;
-int debug_indent;
-
-void debug(const char *msg, ...)
-{
-       if (!debug_mode)
-               return;
-       va_list args;
-       va_start(args, msg);
-       fprintf(stderr, "%*s", debug_indent, "");
-       vfprintf(stderr, msg, args);
-       fputc('\n', stderr);
-       va_end(args);
-}
-
-void warn(const char *msg, ...)
-{
-       va_list args;
-       va_start(args, msg);
-       fprintf(stderr, "WARNING: ");
-       vfprintf(stderr, msg, args);
-       fputc('\n', stderr);
-       va_end(args);
-}
-
-void die(const char *msg, ...)
-{
-       va_list args;
-       va_start(args, msg);
-       fprintf(stderr, "ERROR: ");
-       vfprintf(stderr, msg, args);
-       fputc('\n', stderr);
-       va_end(args);
-       exit(1);
-}
-
-void bad(const char *msg, ...)
-{
-       va_list args;
-       va_start(args, msg);
-       char buf[1024];
-       vsnprintf(buf, sizeof(buf), msg, args);
-       va_end(args);
-
-       printf("error: %s\n", buf);
-       die("BAD: %s", buf);
-}
-
 /*** Transformation matrices ***/
 
 // Construct string representation of a transformation matrix
@@ -75,9 +22,7 @@ string pdf_matrix::to_string() {
        for (int i=0; i<6; i++) {
                if (i)
                        s += " ";
-               char buf[16];
-               snprintf(buf, sizeof(buf), "%.3f", m[i]);
-               s += buf;
+               s += pdf_coord(m[i], 6);
        }
        return s;
 }
@@ -96,9 +41,11 @@ QPDFObjectHandle BBox::to_array()
 
 string BBox::to_rect()
 {
-       char buf[64];
-       snprintf(buf, sizeof(buf), "%.1f %.1f %.1f %.1f", x_min, y_min, width(), height());
-       return string(buf);
+       return
+               pdf_coord(x_min) + " " +
+               pdf_coord(y_min) + " " +
+               pdf_coord(width()) + " " +
+               pdf_coord(height());
 }
 
 bool BBox::parse(QPDFObjectHandle h)
@@ -119,6 +66,14 @@ bool BBox::parse(QPDFObjectHandle h)
        return true;
 }
 
+BBox::BBox(QPDFObjectHandle box) {
+       if (!parse(box)) {
+               warn("Invalid bounding box, falling back to A4");
+               x_min = 0, x_max = A4_WIDTH;
+               y_min = 0, y_max = A4_HEIGHT;
+       }
+}
+
 void BBox::transform(pdf_matrix &m)
 {
        m.apply(&x_min, &y_min);
@@ -129,6 +84,53 @@ void BBox::transform(pdf_matrix &m)
                swap(y_min, y_max);
 }
 
+BBox BBox::transformed(pdf_matrix &m)
+{
+       BBox b = *this;
+       b.transform(m);
+       return b;
+}
+
+void BBox::join(BBox &with)
+{
+       x_min = min(x_min, with.x_min);
+       x_max = max(x_max, with.x_max);
+       y_min = min(y_min, with.y_min);
+       y_max = max(y_max, with.y_max);
+}
+
+static double clamp(double x, double min, double max)
+{
+       if (x < min)
+               return min;
+       if (x > max)
+               return max;
+       return x;
+}
+
+void BBox::intersect(BBox &with)
+{
+       x_min = clamp(x_min, with.x_min, with.x_max);
+       x_max = clamp(x_max, with.x_min, with.x_max);
+       y_min = clamp(y_min, with.y_min, with.y_max);
+       y_max = clamp(y_max, with.y_min, with.y_max);
+}
+
+void BBox::enlarge(double by)
+{
+       x_min -= by;
+       x_max += by;
+       y_min -= by;
+       y_max += by;
+}
+
+BBox BBox::enlarged(double by)
+{
+       BBox b = *this;
+       b.enlarge(by);
+       return b;
+}
+
 /*** Unicode strings ***/
 
 // Construct PDF representation of a UTF-8 string
@@ -230,3 +232,17 @@ QPDFObjectHandle page_to_xobject(QPDF *out, QPDFObjectHandle page)
        xo_stream.replaceStreamData(ph, QPDFObjectHandle::newNull(), QPDFObjectHandle::newNull());
        return xo_stream;
 }
+
+/*** Formatting of coordinates ***/
+
+string pdf_coord(double x, uint digits)
+{
+       char buf[16];
+       snprintf(buf, sizeof(buf), "%.*f", digits, x);
+       int n = strlen(buf);
+       while (n > 0 && buf[n-1] == '0')
+               buf[--n] = 0;
+       if (n > 0 && buf[n-1] == '.')
+               buf[--n] = 0;
+       return buf;
+}