added pdf2pdf tool
authorMatthias Kramm <kramm@quiss.org>
Sat, 15 Aug 2009 20:39:16 +0000 (22:39 +0200)
committerMatthias Kramm <kramm@quiss.org>
Sat, 15 Aug 2009 20:39:16 +0000 (22:39 +0200)
14 files changed:
.gitignore
config.h.in
configure
configure.in
lib/Makefile.in
lib/devices/pdf.c [new file with mode: 0644]
lib/devices/pdf.h [new file with mode: 0644]
lib/devices/polyops.c
lib/gfxpoly/active.c
lib/pdf/GFXOutputDev.cc
lib/pdf/GFXOutputDev.h
lib/q.h
src/Makefile.in
src/pdf2pdf.c [new file with mode: 0644]

index f7baca2..4b7b50e 100644 (file)
@@ -24,6 +24,7 @@ swfstrings
 swfc 
 swfbbox
 font2swf
+src/pdf2pdf
 gif2swf
 pdf2swf
 as3compile
index 57052d9..e91ada7 100644 (file)
 /* Define if you have the <zlib.h> header file.  */
 #undef HAVE_ZLIB_H
 
+/* Define if you have the <pdflib.h> header file.  */
+#undef HAVE_PDFLIB_H
+
 /* Define if you have the <avifile/version.h> header file.  */
 #undef HAVE_AVIFILE_VERSION_H
 
 #undef HAVE_OUTPUTDEV_H
 
 /* Define if you have the jpeg library (-ljpeg).  */
-/* Define if you have the jpeg library (-ljpeg).  */
 #undef HAVE_LIBJPEG
 
+/* Define if you have the jpeg library (-ljpeg).  */
+#undef HAVE_LIBPDF
+
 /* Define if you have the m library (-lm).  */
 #undef HAVE_LIBM
 
index 28644c5..c804ce3 100755 (executable)
--- a/configure
+++ b/configure
@@ -640,6 +640,8 @@ LIBOBJS
 PNG2SWF
 GIF2SWF
 JPEG2SWF
+PDF2PDF
+DEVICE_PDF
 LIBPDF
 PDF2SWF
 HAVE_PYTHON_IMAGING
@@ -4288,6 +4290,83 @@ if test "x$ZLIBMISSING" = "xtrue";then
 fi
 
 
+{ $as_echo "$as_me:$LINENO: checking for PDF_open_file in -lpdf" >&5
+$as_echo_n "checking for PDF_open_file in -lpdf... " >&6; }
+if test "${ac_cv_lib_pdf_PDF_open_file+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpdf  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char PDF_open_file ();
+int
+main ()
+{
+return PDF_open_file ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+        test "$cross_compiling" = yes ||
+        $as_test_x conftest$ac_exeext
+       }; then
+  ac_cv_lib_pdf_PDF_open_file=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_pdf_PDF_open_file=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pdf_PDF_open_file" >&5
+$as_echo "$ac_cv_lib_pdf_PDF_open_file" >&6; }
+if test "x$ac_cv_lib_pdf_PDF_open_file" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPDF 1
+_ACEOF
+
+  LIBS="-lpdf $LIBS"
+
+else
+  PDFLIBMISSING=true
+fi
+
+
 { $as_echo "$as_me:$LINENO: checking for jpeg_write_raw_data in -ljpeg" >&5
 $as_echo_n "checking for jpeg_write_raw_data in -ljpeg... " >&6; }
 if test "${ac_cv_lib_jpeg_jpeg_write_raw_data+set}" = set; then
@@ -5417,7 +5496,8 @@ done
 
 
 
-for ac_header in zlib.h gif_lib.h io.h wchar.h jpeglib.h assert.h signal.h pthread.h sys/stat.h sys/mman.h sys/types.h dirent.h sys/bsdtypes.h sys/ndir.h sys/dir.h ndir.h time.h sys/time.h sys/resource.h
+
+for ac_header in zlib.h gif_lib.h io.h wchar.h jpeglib.h assert.h signal.h pthread.h sys/stat.h sys/mman.h sys/types.h dirent.h sys/bsdtypes.h sys/ndir.h sys/dir.h ndir.h time.h sys/time.h sys/resource.h pdflib.h
 do
 as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@@ -10122,6 +10202,9 @@ if test "x$JPEGLIBMISSING" = "xtrue";then
     DISABLEJPEG2SWF=true
     PARTIAL=true
 fi
+if test "x$PDFLIBMISSING" = "xtrue";then
+    DISABLEPDF2PDF=true;
+fi
 #if test "x$T1LIBMISSING" = "xtrue";then
 #    MISSINGLIBS="${MISSINGLIBS} t1lib"
 #fi
@@ -10131,6 +10214,9 @@ if test "x$UNGIFMISSING" = "xtrue";then
     PARTIAL=true
 fi
 
+if test "x${ac_cv_header_pdflib_h}" '!=' "xyes";then
+    DISABLEPDF2PDF=true;
+fi
 if test "x${ac_cv_header_jpeglib_h}" '!=' "xyes"; then
     DISABLEPDF2SWF=true;
     DISABLEJPEG2SWF=true;
 
 
 
+PDF2PDF='pdf2pdf$(E)'
+DEVICE_PDF='devices/pdf.$(O)'
+if test "x${DISABLEPDF2PDF}" = "xtrue"; then
+  #echo "* Disabling pdf2pdf tool..."
+  PDF2PDF=
+  DEVICE_PDF=
+fi
+
+
+
 if test "x${ZLIBMISSING}" = "xtrue"; then
   echo
   echo "* Warning! Without zlib, you will not be able to read"
index 4c05912..5dae635 100644 (file)
@@ -223,7 +223,8 @@ if test "x$ZLIBMISSING" = "xtrue";then
     echo
     exit
 fi
+
+AC_CHECK_LIB(pdf, PDF_open_file,, PDFLIBMISSING=true)
 AC_CHECK_LIB(jpeg, jpeg_write_raw_data,, JPEGLIBMISSING=true)
 AC_CHECK_LIB(ungif, DGifOpen,, UNGIFMISSING=true)
 if test "$UNGIFMISSING";then
@@ -243,7 +244,7 @@ dnl Checks for header files.
  AC_HEADER_DIRENT
  AC_HEADER_STDC
 
- AC_CHECK_HEADERS(zlib.h gif_lib.h io.h wchar.h jpeglib.h assert.h signal.h pthread.h sys/stat.h sys/mman.h sys/types.h dirent.h sys/bsdtypes.h sys/ndir.h sys/dir.h ndir.h time.h sys/time.h sys/resource.h)
+ AC_CHECK_HEADERS(zlib.h gif_lib.h io.h wchar.h jpeglib.h assert.h signal.h pthread.h sys/stat.h sys/mman.h sys/types.h dirent.h sys/bsdtypes.h sys/ndir.h sys/dir.h ndir.h time.h sys/time.h sys/resource.h pdflib.h)
 
 AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
 AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])
@@ -389,6 +390,9 @@ if test "x$JPEGLIBMISSING" = "xtrue";then
     DISABLEJPEG2SWF=true
     PARTIAL=true
 fi
+if test "x$PDFLIBMISSING" = "xtrue";then
+    DISABLEPDF2PDF=true;
+fi
 #if test "x$T1LIBMISSING" = "xtrue";then
 #    MISSINGLIBS="${MISSINGLIBS} t1lib"
 #fi
@@ -398,6 +402,9 @@ if test "x$UNGIFMISSING" = "xtrue";then
     PARTIAL=true
 fi
 
+if test "x${ac_cv_header_pdflib_h}" '!=' "xyes";then
+    DISABLEPDF2PDF=true;
+fi
 if test "x${ac_cv_header_jpeglib_h}" '!=' "xyes"; then
     DISABLEPDF2SWF=true;
     DISABLEJPEG2SWF=true;
@@ -458,6 +465,16 @@ fi
 AC_SUBST(PDF2SWF)
 AC_SUBST(LIBPDF)
 
+PDF2PDF='pdf2pdf$(E)'
+DEVICE_PDF='devices/pdf.$(O)'
+if test "x${DISABLEPDF2PDF}" = "xtrue"; then
+  #echo "* Disabling pdf2pdf tool..."
+  PDF2PDF=
+  DEVICE_PDF=
+fi
+AC_SUBST(DEVICE_PDF)
+AC_SUBST(PDF2PDF)
+
 if test "x${ZLIBMISSING}" = "xtrue"; then
   echo
   echo "* Warning! Without zlib, you will not be able to read"
index 8a5ac6c..e1d2295 100644 (file)
@@ -3,9 +3,7 @@ srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 include ../Makefile.common
 
-DEVICES = devices/swf.$(O) #devices/lrf.$(O) devices/opengl.$(O)
-
-all: librfxswf$(A) libpdf$(A) libbase$(A) libgfx$(A) libgfxswf$(A) libocr$(A) $(DEVICES)
+all: librfxswf$(A) libpdf$(A) libbase$(A) libgfx$(A) libgfxswf$(A) libocr$(A)
 
 lame_objects = lame/psymodel.$(O) lame/fft.$(O) lame/newmdct.$(O) lame/quantize.$(O) lame/takehiro.$(O) lame/reservoir.$(O) lame/quantize_pvt.$(O) lame/vbrquantize.$(O) lame/encoder.$(O) lame/id3tag.$(O) lame/version.$(O) lame/tables.$(O) lame/util.$(O) lame/bitstream.$(O) lame/set_get.$(O) lame/VbrTag.$(O) lame/lame.$(O)
 lame_in_source = @lame_in_source@
@@ -21,7 +19,7 @@ gfxpoly_objects = gfxpoly/active.$(O) gfxpoly/convert.$(O) gfxpoly/poly.$(O) gfx
 rfxswf_modules =  modules/swfbits.c modules/swfaction.c modules/swfdump.c modules/swfcgi.c modules/swfbutton.c modules/swftext.c modules/swffont.c modules/swftools.c modules/swfsound.c modules/swfshape.c modules/swfobject.c modules/swfdraw.c modules/swffilter.c modules/swfrender.c h.263/swfvideo.c
 
 base_objects=q.$(O) utf8.$(O) png.$(O) jpeg.$(O) wav.$(O) mp3.$(O) os.$(O) bitio.$(O) log.$(O) mem.$(O) 
-gfx_objects=gfxtools.$(O) gfxfont.$(O) devices/dummy.$(O) devices/file.$(O) devices/render.$(O) devices/text.$(O) devices/record.$(O) devices/ops.$(O) devices/polyops.$(O) devices/bbox.$(O) devices/rescale.$(O) @DEVICE_OPENGL@
+gfx_objects=gfxtools.$(O) gfxfont.$(O) devices/dummy.$(O) devices/file.$(O) devices/render.$(O) devices/text.$(O) devices/record.$(O) devices/ops.$(O) devices/polyops.$(O) devices/bbox.$(O) devices/rescale.$(O) @DEVICE_OPENGL@ @DEVICE_PDF@
 
 rfxswf_objects=modules/swfaction.$(O) modules/swfbits.$(O) modules/swfbutton.$(O) modules/swfcgi.$(O) modules/swfdraw.$(O) modules/swfdump.$(O) modules/swffilter.$(O) modules/swffont.$(O) modules/swfobject.$(O) modules/swfrender.$(O) modules/swfshape.$(O) modules/swfsound.$(O) modules/swftext.$(O) modules/swftools.$(O)
 ocr_objects=gocr/box.$(O) gocr/database.$(O) gocr/detect.$(O) gocr/job.$(O) gocr/lines.$(O) gocr/list.$(O) gocr/ocr0.$(O) gocr/ocr0n.$(O) gocr/ocr1.$(O) gocr/otsu.$(O) gocr/output.$(O) gocr/pgm2asc.$(O) gocr/pixel.$(O) gocr/progress.$(O) gocr/remove.$(O) gocr/unicode.$(O)
@@ -168,7 +166,7 @@ uninstall:
 
 clean: 
        rm -f *.o *.obj *.lo *.a *.lib *.la gmon.out
-       for dir in modules devices swf as3 h.263;do rm -f $$dir/*.o $$dir/*.obj $$dir/*.lo $$dir/*.a $$dir/*.lib $$dir/*.la $$dir/gmon.out;done
+       for dir in modules devices swf as3 h.263 gfxpoly;do rm -f $$dir/*.o $$dir/*.obj $$dir/*.lo $$dir/*.a $$dir/*.lib $$dir/*.la $$dir/gmon.out;done
        cd lame && $(MAKE) clean && cd .. || true
        cd action && $(MAKE) clean && cd ..
        cd python && $(MAKE) clean && cd ..
diff --git a/lib/devices/pdf.c b/lib/devices/pdf.c
new file mode 100644 (file)
index 0000000..720abd1
--- /dev/null
@@ -0,0 +1,254 @@
+/* pdf.c
+
+   Part of the swftools package.
+
+   Copyright (c) 2007 Matthias Kramm <kramm@quiss.org> 
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <memory.h>
+#include <pdflib.h>
+#include "../types.h"
+#include "../mem.h"
+#include "../gfxdevice.h"
+#include "../gfxtools.h"
+
+typedef struct _internal {
+    PDF* p;
+    char*tempfile;
+} internal_t;
+
+int pdf_setparameter(gfxdevice_t*dev, const char*key, const char*value)
+{
+    internal_t*i = (internal_t*)dev->internal;
+    return 0;
+}
+
+void pdf_startpage(gfxdevice_t*dev, int width, int height)
+{
+    internal_t*i = (internal_t*)dev->internal;
+   
+    i->tempfile = strdup("tmp.pdf");
+    PDF_open_file(i->p, i->tempfile);
+    PDF_set_parameter(i->p, "usercoordinates", "true");
+    PDF_set_parameter(i->p, "topdown", "true");
+    PDF_begin_page(i->p, width, height);
+    PDF_set_parameter(i->p, "fillrule", "evenodd");
+}
+
+static int mkline(gfxline_t*line, PDF*p)
+{
+    int ret = 0;
+    double x=0,y=0;
+    while(line) {
+       if(line->type == gfx_moveTo) {
+           PDF_moveto(p, line->x, line->y);
+       } else if(line->type == gfx_lineTo) {
+           PDF_lineto(p, line->x, line->y);
+           ret = 1;
+       } else {
+           /* when converting a quadratic bezier to a cubic bezier, the
+              two new control points are both 2/3 the way from the
+              endpoints to the old control point */
+           double c1x = (x + line->sx*2)/3;
+           double c1y = (y + line->sy*2)/3;
+           double c2x = (line->x + line->sx*2)/3;
+           double c2y = (line->y + line->sy*2)/3;
+           PDF_curveto(p, c1x, c1y, c2x, c2y, line->x, line->y);
+           ret = 1;
+       }
+       x = line->x;
+       y = line->y;
+       line = line->next;
+    }
+    return ret;
+}
+
+void pdf_startclip(gfxdevice_t*dev, gfxline_t*line)
+{
+    internal_t*i = (internal_t*)dev->internal;
+    PDF_save(i->p);
+    PDF_set_parameter(i->p, "fillrule", "evenodd");
+    if(mkline(line, i->p))
+       PDF_clip(i->p);
+    else   
+       ; // TODO: not sure about this
+
+}
+void pdf_endclip(gfxdevice_t*dev)
+{
+    internal_t*i = (internal_t*)dev->internal;
+    PDF_restore(i->p);
+}
+void pdf_stroke(gfxdevice_t*dev, gfxline_t*line, gfxcoord_t width, gfxcolor_t*color, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit)
+{
+    internal_t*i = (internal_t*)dev->internal;
+    PDF_setlinewidth(i->p, width);
+    PDF_setlinecap(i->p, cap_style==gfx_capButt?0:(cap_style==gfx_capRound?1:2));
+    PDF_setlinejoin(i->p, joint_style==gfx_joinMiter?0:(joint_style==gfx_joinRound?1:2));
+    PDF_setrgbcolor_stroke(i->p, color->r/255.0, color->g/255.0, color->b/255.0);
+    if(joint_style==gfx_joinMiter)
+       PDF_setmiterlimit(i->p, miterLimit);
+    if(mkline(line, i->p))
+       PDF_stroke(i->p);
+}
+
+void pdf_fill(gfxdevice_t*dev, gfxline_t*line, gfxcolor_t*color)
+{
+    internal_t*i = (internal_t*)dev->internal;
+    PDF_setrgbcolor_fill(i->p, color->r/255.0, color->g/255.0, color->b/255.0);
+    PDF_set_parameter(i->p, "fillrule", "evenodd");
+       
+    if(mkline(line, i->p)) {
+       PDF_fill(i->p);
+    }
+}
+
+void pdf_fillbitmap(gfxdevice_t*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform)
+{
+    internal_t*i = (internal_t*)dev->internal;
+
+    //PDFLIB_API int PDFLIB_CALL
+    //PDF_load_image(i->pPDF *p, const char *imagetype, const char *filename, int len, const char *optlist);
+}
+
+void pdf_fillgradient(gfxdevice_t*dev, gfxline_t*line, gfxgradient_t*gradient, gfxgradienttype_t type, gfxmatrix_t*matrix)
+{
+    internal_t*i = (internal_t*)dev->internal;
+}
+
+void pdf_addfont(gfxdevice_t*dev, gfxfont_t*font)
+{
+    internal_t*i = (internal_t*)dev->internal;
+}
+
+void pdf_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyphnr, gfxcolor_t*color, gfxmatrix_t*matrix)
+{
+    internal_t*i = (internal_t*)dev->internal;
+    if(!font)
+       return;
+    /* align characters to whole pixels */
+    matrix->tx = (int)matrix->tx;
+    matrix->ty = (int)matrix->ty;
+
+    gfxglyph_t*glyph = &font->glyphs[glyphnr];
+    gfxline_t*line2 = gfxline_clone(glyph->line);
+    gfxline_transform(line2, matrix);
+    PDF_setrgbcolor_fill(i->p, color->r/255.0, color->g/255.0, color->b/255.0);
+    PDF_set_parameter(i->p, "fillrule", "evenodd");
+    
+    if(mkline(line2, i->p)) {
+       PDF_fill(i->p);
+    }
+    gfxline_free(line2);
+    return;
+}
+
+void pdf_drawlink(gfxdevice_t*dev, gfxline_t*line, const char*action)
+{
+    internal_t*i = (internal_t*)dev->internal;
+}
+
+void pdf_endpage(gfxdevice_t*dev)
+{
+    internal_t*i = (internal_t*)dev->internal;
+    PDF_end_page(i->p);
+    PDF_close(i->p);
+    PDF_delete(i->p);
+}
+
+typedef struct pdfresult_internal {
+    char*tempfile;
+} pdfresult_internal_t;
+
+void pdfresult_destroy(gfxresult_t*gfx)
+{
+    pdfresult_internal_t*i = (pdfresult_internal_t*)gfx->internal;
+    free(i->tempfile);
+    free(gfx->internal);gfx->internal = 0;
+    free(gfx);
+}
+
+int pdfresult_save(gfxresult_t*gfx, const char*filename)
+{
+    pdfresult_internal_t*i = (pdfresult_internal_t*)gfx->internal;
+    FILE*fi = fopen(i->tempfile, "rb");
+    FILE*fo = fopen(filename, "wb");
+    if(!fo) {
+       perror(filename);
+       return -1;
+    }
+    char buffer[4096];
+    int size = 0;
+    while((size = fread(buffer, 1, 4096, fi))) {
+       fwrite(buffer, 1, size, fo);
+    }
+    fclose(fi);
+    fclose(fo);
+    return 0;
+}
+
+void* pdfresult_get(gfxresult_t*gfx, const char*name)
+{
+    return 0; 
+}
+
+gfxresult_t* pdf_finish(gfxdevice_t*dev)
+{
+    internal_t*i = (internal_t*)dev->internal;
+
+    gfxresult_t*result = (gfxresult_t*)malloc(sizeof(gfxresult_t));
+    memset(result, 0, sizeof(gfxresult_t));
+    result->save = pdfresult_save;
+    result->get = pdfresult_get;
+    result->destroy = pdfresult_destroy;
+    result->internal = 0;
+    result->internal = malloc(sizeof(pdfresult_internal_t));
+    pdfresult_internal_t*ri = (pdfresult_internal_t*)result->internal;
+    ri->tempfile = i->tempfile;i->tempfile=0;
+    free(dev->internal);dev->internal = 0;i=0;
+    return result;
+}
+
+void gfxdevice_pdf_init(gfxdevice_t*dev)
+{
+    internal_t*i = (internal_t*)rfx_calloc(sizeof(internal_t));
+    memset(dev, 0, sizeof(gfxdevice_t));
+
+    dev->name = "pdf";
+
+    dev->internal = i;
+
+    dev->setparameter = pdf_setparameter;
+    dev->startpage = pdf_startpage;
+    dev->startclip = pdf_startclip;
+    dev->endclip = pdf_endclip;
+    dev->stroke = pdf_stroke;
+    dev->fill = pdf_fill;
+    dev->fillbitmap = pdf_fillbitmap;
+    dev->fillgradient = pdf_fillgradient;
+    dev->addfont = pdf_addfont;
+    dev->drawchar = pdf_drawchar;
+    dev->drawlink = pdf_drawlink;
+    dev->endpage = pdf_endpage;
+    dev->finish = pdf_finish;
+
+    i->p = PDF_new();
+}
+
diff --git a/lib/devices/pdf.h b/lib/devices/pdf.h
new file mode 100644 (file)
index 0000000..e64ca7e
--- /dev/null
@@ -0,0 +1,37 @@
+/* pdf.h
+   Header file for pdf.c
+
+   Part of the swftools package.
+
+   Copyright (c) 2009 Matthias Kramm <kramm@quiss.org> 
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef __gfxdevice_pdf_h__
+#define __gfxdevice_pdf_h__
+
+#include "../gfxdevice.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void gfxdevice_pdf_init(gfxdevice_t*dev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__gfxdevice_pdf_h__
index fea200b..de03533 100644 (file)
@@ -105,7 +105,11 @@ void polyops_startclip(struct _gfxdevice*dev, gfxline_t*line)
        a gfxline into a gfxpoly- for polygons which are too
        complex or just degenerate, this might fail. So handle
        all the cases where polygon conversion or intersection
-       might go awry */
+       might go awry 
+       UPDATE: this is not needed anymore. The new gfxpoly
+       implementation is stable enough so it always returns
+       a valid result. Still, it's good practice.
+     */
     if(!poly && !oldclip) {
        i->out->startclip(i->out,line);
        currentclip = 0;
index e9270e4..2904e08 100644 (file)
@@ -375,7 +375,7 @@ static void move_to_root(actlist_t*a, segment_t*s)
     }
 }
 
-static int actlist_splay(actlist_t*a, point_t p1, point_t p2)
+static void actlist_splay(actlist_t*a, point_t p1, point_t p2)
 {
     if(!a->list) return;
 
index 6c4a3a9..2d80cb2 100644 (file)
@@ -599,6 +599,7 @@ GFXOutputDev::GFXOutputDev(InfoOutputDev*info, PDFDoc*doc)
     this->config_remapunicode=0;
     this->config_transparent=0;
     this->config_extrafontdata = 0;
+    this->config_drawonlyshapes = 0;
     this->config_disable_polygon_conversion = 0;
     this->config_multiply = 1;
     this->page2page = 0;
@@ -615,6 +616,8 @@ void GFXOutputDev::setParameter(const char*key, const char*value)
         this->config_remapunicode = atoi(value);
     } else if(!strcmp(key,"transparent")) {
         this->config_transparent = atoi(value);
+    } else if(!strcmp(key,"drawonlyshapes")) {
+        this->config_drawonlyshapes = atoi(value);
     } else if(!strcmp(key,"extrafontdata")) {
         this->config_extrafontdata = atoi(value);
     } else if(!strcmp(key,"convertgradients")) {
@@ -1219,20 +1222,21 @@ gfxcolor_t getFillColor(GfxState * state)
     return col;
 }
 
-void GFXOutputDev::fillGfxLine(GfxState *state, gfxline_t*line) 
+void GFXOutputDev::fillGfxLine(GfxState *state, gfxline_t*line, char evenodd) 
 {
     gfxcolor_t col = getFillColor(state);
 
     if(getLogLevel() >= LOGLEVEL_TRACE)  {
-        msg("<trace> fill %02x%02x%02x%02x", col.r, col.g, col.b, col.a);
+        msg("<trace> %sfill %02x%02x%02x%02x%s", evenodd?"eo":"", col.r, col.g, col.b, col.a);
         dump_outline(line);
     }
     device->fill(device, line, &col);
 }
 
-void GFXOutputDev::clipToGfxLine(GfxState *state, gfxline_t*line) 
+void GFXOutputDev::clipToGfxLine(GfxState *state, gfxline_t*line, char evenodd) 
 {
     if(getLogLevel() >= LOGLEVEL_TRACE)  {
+        msg("<trace> %sclip", evenodd?"eo":"");
         dump_outline(line);
     }
     gfxbbox_t bbox = gfxline_getbbox(line);
@@ -1252,7 +1256,7 @@ void GFXOutputDev::clip(GfxState *state)
        gfxline_free(line);
        line = line2;
     }
-    clipToGfxLine(state, line);
+    clipToGfxLine(state, line, 0);
     gfxline_free(line);
 }
 
@@ -1260,7 +1264,7 @@ void GFXOutputDev::eoClip(GfxState *state)
 {
     GfxPath * path = state->getPath();
     gfxline_t*line = gfxPath_to_gfxline(state, path, 1, user_movex + clipmovex, user_movey + clipmovey);
-    clipToGfxLine(state, line);
+    clipToGfxLine(state, line, 1);
     gfxline_free(line);
 }
 void GFXOutputDev::clipToStrokePath(GfxState *state)
@@ -1415,7 +1419,7 @@ void GFXOutputDev::drawChar(GfxState *state, double x, double y,
     
     msg("<debug> drawChar(%f,%f,c='%c' (%d), u=%d <%d>) CID=%d render=%d glyphid=%d font=%08x",m.tx,m.ty,(charid&127)>=32?charid:'?', charid, u, uLen, font->isCIDFont(), render, glyphid, current_gfxfont);
 
-    if(render == RENDER_FILL || render == RENDER_INVISIBLE) {
+    if((render == RENDER_FILL && !config_drawonlyshapes) || render == RENDER_INVISIBLE) {
        device->drawchar(device, current_gfxfont, glyphid, &col, &m);
     } else {
        msg("<debug> Drawing glyph %d as shape", charid);
@@ -1453,11 +1457,11 @@ void GFXOutputDev::endString(GfxState *state)
           however */
        device->setparameter(device, "mark","TXT");
        if((render&3) == RENDER_FILL) {
-           fillGfxLine(state, current_text_stroke);
+           fillGfxLine(state, current_text_stroke, 0);
            gfxline_free(current_text_stroke);
            current_text_stroke = 0;
        } else if((render&3) == RENDER_FILLSTROKE) {
-           fillGfxLine(state, current_text_stroke);
+           fillGfxLine(state, current_text_stroke, 0);
            strokeGfxline(state, current_text_stroke,0);
            gfxline_free(current_text_stroke);
            current_text_stroke = 0;
@@ -1477,7 +1481,7 @@ void GFXOutputDev::endTextObject(GfxState *state)
     
     if(current_text_clip) {
        device->setparameter(device, "mark","TXT");
-       clipToGfxLine(state, current_text_clip);
+       clipToGfxLine(state, current_text_clip, 0);
        device->setparameter(device, "mark","");
        gfxline_free(current_text_clip);
        current_text_clip = 0;
@@ -2473,7 +2477,7 @@ void GFXOutputDev::fill(GfxState *state)
         gfxline_free(line);
         line = line2;
     }
-    fillGfxLine(state, line);
+    fillGfxLine(state, line, 0);
     gfxline_free(line);
 }
 
@@ -2484,7 +2488,7 @@ void GFXOutputDev::eoFill(GfxState *state)
 
     GfxPath * path = state->getPath();
     gfxline_t*line= gfxPath_to_gfxline(state, path, 1, user_movex + clipmovex, user_movey + clipmovey);
-    fillGfxLine(state, line);
+    fillGfxLine(state, line, 1);
     gfxline_free(line);
 }
 
index 1a820a7..0b07e4f 100644 (file)
@@ -228,8 +228,8 @@ public:
                                   Stream *maskStr, int maskWidth, int maskHeight, GBool maskInvert, GfxImageColorMap*maskColorMap);
 
   void strokeGfxline(GfxState *state, gfxline_t*line, int flags);
-  void clipToGfxLine(GfxState *state, gfxline_t*line);
-  void fillGfxLine(GfxState *state, gfxline_t*line);
+  void clipToGfxLine(GfxState *state, gfxline_t*line, char evenodd);
+  void fillGfxLine(GfxState *state, gfxline_t*line, char evenodd);
 
   gfxfont_t* createGfxFont(GfxFont*xpdffont, FontInfo*src);
 
@@ -284,6 +284,7 @@ public:
   int config_disable_polygon_conversion;
   int config_multiply;
   int config_bigchar;
+  int config_drawonlyshapes;
   double config_fontquality;
 };
 
diff --git a/lib/q.h b/lib/q.h
index df1c074..585d420 100644 (file)
--- a/lib/q.h
+++ b/lib/q.h
@@ -23,6 +23,7 @@
 #define __q_h__
 
 #include <stdio.h>
+#include "mem.h"
 
 #ifdef __cplusplus
 extern "C" {
index 3bb42bb..3304e62 100644 (file)
@@ -3,7 +3,7 @@ srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 include ../Makefile.common
 
-programs = wav2swf$(E) @PNG2SWF@ swfcombine$(E) swfstrings$(E) swfextract$(E) swfdump$(E) swfc$(E) @JPEG2SWF@ @GIF2SWF@ swfbbox$(E) font2swf$(E) swfrender$(E) as3compile$(E) @PDF2SWF@
+programs = wav2swf$(E) @PNG2SWF@ swfcombine$(E) swfstrings$(E) swfextract$(E) swfdump$(E) swfc$(E) @JPEG2SWF@ @GIF2SWF@ swfbbox$(E) font2swf$(E) swfrender$(E) as3compile$(E) @PDF2SWF@ @PDF2PDF@
 opt_programs = swfbytes$(E)
 
 all: $(programs)
@@ -14,6 +14,8 @@ png2swf.$(O): png2swf.c
        $(C) png2swf.c -o $@
 pdf2swf.$(O): pdf2swf.c
        $(C) pdf2swf.c -o $@
+pdf2pdf.$(O): pdf2pdf.c
+       $(C) pdf2pdf.c -o $@
 gif2swf.$(O): gif2swf.c
        $(C) gif2swf.c -o $@
 swfcombine.$(O): swfcombine.c
@@ -99,10 +101,13 @@ swfrender$(E): swfrender.$(O) ../lib/librfxswf$(A) ../lib/libgfx$(A) ../lib/libb
        $(L) swfrender.$(O) -o $@ ../lib/librfxswf$(A) ../lib/libgfx$(A) ../lib/libgfxswf$(A) ../lib/libbase$(A) $(LIBS) 
        $(STRIP) $@
 
-PDF2SWF_OBJ=../lib/libpdf$(A) ../lib/devices/polyops.$(O) ../lib/devices/swf.$(O) ../lib/librfxswf$(A) ../lib/libgfx$(A) ../lib/libbase$(A)
+PDF2SWF_OBJ=../lib/libgfxswf$(A) ../lib/librfxswf$(A) ../lib/libpdf$(A) ../lib/libgfx$(A) ../lib/libbase$(A)
 pdf2swf$(E): pdf2swf.$(O) $(PDF2SWF_OBJ)
        $(LL) pdf2swf.$(O) -o $@ $(PDF2SWF_OBJ) $(LIBS) $(CXXLIBS)
        $(STRIP) $@
+pdf2pdf$(E): pdf2pdf.$(O) $(PDF2SWF_OBJ)
+       $(LL) pdf2pdf.$(O) -o $@ $(PDF2SWF_OBJ) $(LIBS) $(CXXLIBS)
+       $(STRIP) $@
 swfc$(E): parser.$(O) swfc.$(O) swfc-feedback.$(O) swfc-history.$(O) swfc-interpolation.$(O) ../lib/librfxswf$(A) ../lib/libbase$(A) 
        $(L) parser.$(O) swfc.$(O) swfc-feedback.$(O) swfc-history.$(O) swfc-interpolation.$(O) -o $@ ../lib/librfxswf$(A) ../lib/libbase$(A) $(LIBS)
        $(STRIP) $@
diff --git a/src/pdf2pdf.c b/src/pdf2pdf.c
new file mode 100644 (file)
index 0000000..f642df6
--- /dev/null
@@ -0,0 +1,233 @@
+/* pdf2pdf.c
+   main routine for pdf2pdf(1)
+
+   Part of the swftools package.
+   
+   Copyright (c) 2009 Matthias Kramm <kramm@quiss.org> 
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include "../config.h"
+#include "../lib/args.h"
+#include "../lib/os.h"
+#include "../lib/gfxsource.h"
+#include "../lib/gfxdevice.h"
+#include "../lib/gfxpoly.h"
+#include "../lib/devices/rescale.h"
+#include "../lib/devices/polyops.h"
+#include "../lib/devices/pdf.h"
+#include "../lib/readers/image.h"
+#include "../lib/readers/swf.h"
+#include "../lib/pdf/pdf.h"
+#include "../lib/log.h"
+
+static gfxsource_t*driver = 0;
+
+static char * outputname = 0;
+static int loglevel = 3;
+static char * pagerange = 0;
+static char * filename = 0;
+static const char * format = "ocr";
+
+int args_callback_option(char*name,char*val) {
+    if (!strcmp(name, "o"))
+    {
+       outputname = val;
+       return 1;
+    }
+    else if (!strcmp(name, "v"))
+    {
+       loglevel ++;
+        setConsoleLogging(loglevel);
+       return 0;
+    }
+    else if (!strcmp(name, "f"))
+    {
+       format = val;
+       return 1;
+    }
+    else if (!strcmp(name, "q"))
+    {
+       loglevel --;
+        setConsoleLogging(loglevel);
+       return 0;
+    }
+    else if (name[0]=='p')
+    {
+       do {
+           name++;
+       } while(*name == 32 || *name == 13 || *name == 10 || *name == '\t');
+
+       if(*name) {
+           pagerange = name;
+           return 0;
+       } 
+       pagerange = val;        
+       return 1;
+    }
+    else if (!strcmp(name, "s"))
+    {
+        if(!driver) {
+            fprintf(stderr, "Specify input file before -s\n");
+            exit(1);
+        }
+       char*s = strdup(val);
+       char*c = strchr(s, '=');
+       if(c && *c && c[1])  {
+           *c = 0;
+           c++;
+           driver->set_parameter(driver, s,c);
+       } else {
+           driver->set_parameter(driver, s,"1");
+        }
+        free(s);
+       return 1;
+    }
+    else if (!strcmp(name, "V"))
+    {  
+       printf("pdf2swf - part of %s %s\n", PACKAGE, VERSION);
+       exit(0);
+    }
+    else 
+    {
+       fprintf(stderr, "Unknown option: -%s\n", name);
+       exit(1);
+    }
+    return 0;
+}
+
+struct options_t options[] =
+{{"o","output"},
+ {"q","quiet"},
+ {"V","version"},
+ {"s","set"},
+ {"p","pages"},
+ {0,0}
+};
+
+int args_callback_longoption(char*name,char*val) {
+    return args_long2shortoption(options, name, val);
+}
+
+int args_callback_command(char*name, char*val) {
+    if (!filename) {
+
+        filename = name;
+
+        if(strstr(filename, ".pdf") || strstr(filename, ".PDF")) {
+            msg("<verbose> Treating file as PDF");
+            driver = gfxsource_pdf_create();
+        } else if(strstr(filename, ".swf") || strstr(filename, ".SWF")) {
+            msg("<verbose> Treating file as SWF");
+            driver = gfxsource_swf_create();
+        } else if(strstr(filename, ".jpg") || strstr(filename, ".JPG") ||
+                  strstr(filename, ".png") || strstr(filename, ".PNG")) {
+            msg("<verbose> Treating file as Image");
+            driver = gfxsource_image_create();
+        } else {
+            driver = gfxsource_pdf_create();
+       }
+    } else {
+       if(outputname)
+       {
+            fprintf(stderr, "Error: Do you want the output to go to %s or to %s?", 
+                    outputname, name);
+            exit(1);
+       }
+       outputname = name;
+    }
+    return 0;
+}
+
+void args_callback_usage(char*name)
+{
+}
+
+int main(int argn, char *argv[])
+{
+    processargs(argn, argv);
+    initLog(0,-1,0,0,-1,loglevel);
+    
+    if(!filename) {
+       fprintf(stderr, "Please specify an input file\n");
+       exit(1);
+    }
+    
+    if(!outputname)
+    {
+       if(filename) {
+           outputname = stripFilename(filename, ".print.pdf");
+           msg("<notice> Output filename not given. Writing to %s", outputname);
+       } 
+    }
+    if(!outputname)
+    {
+       fprintf(stderr, "Please use -o to specify an output file\n");
+       exit(1);
+    }
+
+    is_in_range(0x7fffffff, pagerange);
+    if(pagerange)
+       driver->set_parameter(driver, "pages", pagerange);
+
+    if(!filename) {
+       args_callback_usage(argv[0]);
+       exit(0);
+    }
+
+    gfxdocument_t* doc = driver->open(driver, filename);
+    doc->set_parameter(doc, "drawonlyshapes", "1");
+    doc->set_parameter(doc, "disable_polygon_conversion", "1");
+
+    if(!doc) {
+        msg("<error> Couldn't open %s", filename);
+        exit(1);
+    }
+
+    gfxdevice_t _out,*out=&_out;
+    gfxdevice_pdf_init(out);
+
+    /*gfxdevice_t wrap;
+    gfxdevice_removeclippings_init(&wrap, out);
+    out = &wrap;*/
+
+    int pagenr;
+    for(pagenr = 1; pagenr <= doc->num_pages; pagenr++) 
+    {
+       if(is_in_range(pagenr, pagerange)) {
+           gfxpage_t* page = doc->getpage(doc, pagenr);
+           out->startpage(out, page->width, page->height);
+           page->render(page, out);
+           out->endpage(out);
+           page->destroy(page);
+       }
+    }
+    gfxresult_t*result = out->finish(out);
+    if(result) {
+       if(result->save(result, outputname) < 0) {
+           exit(1);
+       }
+       result->destroy(result);
+    }
+    doc->destroy(doc);
+    driver->destroy(driver);
+    return 0;
+}
+