implemented type3 fonts in pdf2pdf, added fontmatrix tests to testsuite
authorkramm <kramm@thorn.(none)>
Tue, 18 Aug 2009 15:23:00 +0000 (17:23 +0200)
committerkramm <kramm@thorn.(none)>
Tue, 18 Aug 2009 15:23:00 +0000 (17:23 +0200)
config.h.in
configure.in
lib/devices/pdf.c
lib/gfxpoly.c
lib/gfxtools.c
lib/gfxtools.h
spec/textposition.pdf [new file with mode: 0644]
spec/textposition.py [new file with mode: 0644]
src/pdf2pdf.c

index e91ada7..c486e83 100644 (file)
 /* Define if you have the z library (-lz).  */
 #undef HAVE_LIBZ
 
-/* use internal libart library */
-#undef INTERNAL_LIBART
-
-/* Define to 1 if you have the `art_lgpl_2' library (-lart_lgpl_2). */
-#undef HAVE_LIBART_LGPL_2
-
-/* Define to 1 if you have the <libart_lgpl/libart.h> header file. */
-#undef HAVE_LIBART_LGPL_LIBART_H
-
 /* Name of package */
 #undef PACKAGE
 
index 5dae635..b3adafb 100644 (file)
@@ -308,8 +308,6 @@ else
 fi
 AC_SUBST(lame_in_source)
 
-AC_DEFINE([INTERNAL_LIBART], [1], [use internal libart library])
-art_in_source='$(art_objects)'
 splash_in_source='$(splash_objects)'
 xpdf_in_source='$(xpdf_objects)'
 
@@ -331,7 +329,6 @@ dnl         LIBS="$LIBS $POPPLER_LIBS"
 dnl     fi
 dnl fi
 
-AC_SUBST([art_in_source])
 AC_SUBST([xpdf_in_source])
 AC_SUBST([splash_in_source])
 
index ba92ed0..4d223c8 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <unistd.h>
+#include <assert.h>
 #include <memory.h>
 #include <pdflib.h>
 #include <math.h>
@@ -35,6 +36,7 @@
 typedef struct _internal {
     PDF* p;
     char*tempfile;
+    gfxfontlist_t*fontlist;
 } internal_t;
 
 int pdf_setparameter(gfxdevice_t*dev, const char*key, const char*value)
@@ -90,7 +92,6 @@ 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   
@@ -119,7 +120,6 @@ 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);
@@ -151,30 +151,79 @@ void pdf_fillgradient(gfxdevice_t*dev, gfxline_t*line, gfxgradient_t*gradient, g
     internal_t*i = (internal_t*)dev->internal;
 }
 
+static char type3 = 1;
+
 void pdf_addfont(gfxdevice_t*dev, gfxfont_t*font)
 {
     internal_t*i = (internal_t*)dev->internal;
+
+    if(type3) {
+       int fontid = 0;
+       if(!gfxfontlist_hasfont(i->fontlist, font)) {
+
+           static int fontnr = 1;
+           char fontname[32];
+           sprintf(fontname, "font%d", fontnr++);
+           int l = strlen(fontname);
+           char fontname2[64];
+           int t;
+           for(t=0;t<l+1;t++) {
+               fontname2[t*2+0] = fontname[t];
+               fontname2[t*2+1] = 0;
+           }
+
+           PDF_begin_font(i->p, fontname2, l*2, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, "");
+           int num = font->num_glyphs<256-32?font->num_glyphs:256-32;
+           for(t=0;t<num;t++) {
+               gfxglyph_t*g = &font->glyphs[t];
+               gfxbbox_t bbox = gfxline_getbbox(g->line);
+               char name[32];
+               sprintf(name, "chr%d", t+32);
+               PDF_encoding_set_char(i->p, fontname, t+32, name, 0);
+               PDF_begin_glyph(i->p, name, g->advance, bbox.xmin, bbox.ymin, bbox.xmax, bbox.ymax);
+               if(mkline(g->line, i->p))
+                   PDF_fill(i->p);
+               PDF_end_glyph(i->p);
+           }
+           PDF_end_font(i->p);
+           fontid = PDF_load_font(i->p, fontname2, l*2, fontname, "");
+           
+           i->fontlist = gfxfontlist_addfont2(i->fontlist, font, (void*)(ptroff_t)fontid);
+       }
+    }
 }
 
 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);
+    char as_shape = 0;
+    if(!type3) as_shape=1;
+    if(glyphnr>256-32) as_shape=1;
+    gfxmatrix_dump(matrix, stdout, "");
+    if(fabs(matrix->m00 + matrix->m11) > 0.01) as_shape=1;
+    if(fabs(fabs(matrix->m01) + fabs(matrix->m10)) > 0.01) as_shape=1;
+
+    if(as_shape) {
+       gfxline_t*line2 = gfxline_clone(glyph->line);
+       gfxline_transform(line2, matrix);
+       if(mkline(line2, i->p)) {
+           PDF_fill(i->p);
+       }
+       gfxline_free(line2);
+    } else {
+       assert(gfxfontlist_hasfont(i->fontlist, font));
+       int fontid = (int)(ptroff_t)gfxfontlist_getuserdata(i->fontlist, font->id);
+       PDF_setfont(i->p, fontid, matrix->m00);
+       char name[32];
+       sprintf(name, "%c\0", glyphnr+32);
+       PDF_show_xy2(i->p, name, strlen(name), matrix->tx, matrix->ty);
     }
-    gfxline_free(line2);
     return;
 }
 
index 902eaf8..dd97ff4 100644 (file)
 #include "gfxtools.h"
 #include "gfxpoly.h"
 #include "mem.h"
-#ifdef INTERNAL_LIBART
 #include "art/libart.h"
 #include "art/art_svp_intersect.h"
 #include "art/art_svp_ops.h"
-#else
-#include <libart_lgpl/libart.h>
-#include <libart_lgpl/art_svp_intersect.h>
-#include <libart_lgpl/art_svp_ops.h>
-#endif
 #include "log.h"
 #include <assert.h>
 #include <memory.h>
index 9975e6d..d8aef3f 100644 (file)
@@ -795,7 +795,18 @@ char gfxfontlist_hasfont(gfxfontlist_t*list, gfxfont_t*font)
     }
     return 0;
 }
-gfxfontlist_t*gfxfontlist_addfont(gfxfontlist_t*list, gfxfont_t*font)
+void*gfxfontlist_getuserdata(gfxfontlist_t*list, const char*id)
+{
+    gfxfontlist_t*l = list;
+    while(l) {
+       if(!strcmp((char*)l->font->id, id)) {
+           return l->user;
+       }
+       l = l->next;
+    }
+    return 0;
+}
+gfxfontlist_t*gfxfontlist_addfont2(gfxfontlist_t*list, gfxfont_t*font, void*user)
 {
     gfxfontlist_t*last=0,*l = list;
     while(l) {
@@ -810,6 +821,7 @@ gfxfontlist_t*gfxfontlist_addfont(gfxfontlist_t*list, gfxfont_t*font)
     }
     l = (gfxfontlist_t*)rfx_calloc(sizeof(gfxfontlist_t));
     l->font = font;
+    l->user = user;
     l->next = 0;
     if(last) {
        last->next = l;
@@ -818,6 +830,10 @@ gfxfontlist_t*gfxfontlist_addfont(gfxfontlist_t*list, gfxfont_t*font)
        return l;
     }
 }
+gfxfontlist_t*gfxfontlist_addfont(gfxfontlist_t*list, gfxfont_t*font)
+{
+    return gfxfontlist_addfont2(list, font, 0);
+}
 void gfxfontlist_free(gfxfontlist_t*list, char deletefonts)
 {
     gfxfontlist_t*l = list;
index 163138b..ff282a3 100644 (file)
@@ -50,6 +50,7 @@ typedef struct _gfxpoint
 typedef struct _gfxfontlist
 {
     gfxfont_t*font;
+    void*user;
     struct _gfxfontlist*next;
 } gfxfontlist_t;
 
@@ -81,8 +82,10 @@ void gfxmatrix_multiply(gfxmatrix_t*m1, gfxmatrix_t*m2, gfxmatrix_t*dest);
 
 gfxfontlist_t* gfxfontlist_create();
 gfxfontlist_t*gfxfontlist_addfont(gfxfontlist_t*list, gfxfont_t*font);
+gfxfontlist_t*gfxfontlist_addfont2(gfxfontlist_t*list, gfxfont_t*font, void*user);
 gfxfont_t*gfxfontlist_findfont(gfxfontlist_t*list, char*id);
 char gfxfontlist_hasfont(gfxfontlist_t*list, gfxfont_t*font);
+void* gfxfontlist_getuserdata(gfxfontlist_t*list, const char*id);
 void gfxfontlist_free(gfxfontlist_t*list, char deletefonts);
 
 void gfximage_save_jpeg(gfximage_t*img, char*filename, int quality);
diff --git a/spec/textposition.pdf b/spec/textposition.pdf
new file mode 100644 (file)
index 0000000..44743b7
--- /dev/null
@@ -0,0 +1,146 @@
+%PDF-1.6
+%äãÏÒ
+1 0 obj
+[/PDF/ImageB/ImageC/ImageI/Text]
+endobj
+4 0 obj
+<</Length 5 0 R
+/Filter/FlateDecode
+>>
+stream
+x\9cÕTÍ\ e \f¾÷)zÔ\ 3\b\f\1ag<\90,\1a\12\1f@3\13³\1dæû\1f,?ºè\e\10R íW\92æûÊ\ 2\12\ 5-\89R\bTd·\19D
\1e°\ f°;RÒb\18\1e",Z¸ÃæÔ{?àu¸øÃ6<!¿Ce}øÂfPMÃ\9d\9bVOjò\12j½%\84\15hc\1d\89)eJÉ\8fgWì\ 4#\9ca\ 1Á»V[\14¼ÕZ!+g\89jz¼3\15w\97yb\99¨ÆÔL\14ûhNS\eª«¹\15É\1d)ÌDÑ¡ä\1aM¤H×ÜQ\99\17ö7F¬Ä\93úªþ&²ø\f2G\Õüã½\ 1"£$ê
+endstream
+endobj
+5 0 obj
+213
+endobj
+7 0 obj
+<</ProcSet 1 0 R
+/Font<</F0 6 0 R
+>>
+>>
+endobj
+8 0 obj
+<</CreationDate (D:20090818171028+02'00')
+/Producer (PDFlib Lite 7.0.2p8 \(Python 2.6.2/Linux\))
+>>
+endobj
+6 0 obj
+<</Type/Font
+/Subtype/Type1
+/BaseFont/Helvetica-Bold
+/FontDescriptor 9 0 R
+/FirstChar 0
+/LastChar 255
+/Widths[278 278 278 278 278 278 278 278 278 278 278 278 278 278 278 278
+278 278 278 278 278 278 278 278 278 278 278 278 278 278 278 278
+278 333 474 556 556 889 722 238 333 333 389 584 278 333 278 278
+556 556 556 556 556 556 556 556 556 556 333 333 584 584 584 611
+975 722 722 722 722 667 611 778 722 278 556 722 611 833 722 778
+667 778 722 667 611 722 667 944 667 667 611 333 278 333 584 556
+333 556 611 556 611 556 333 611 611 278 278 556 278 889 611 611
+611 611 389 556 333 611 556 778 556 556 500 389 280 389 584 278
+278 278 278 278 278 278 278 278 278 278 278 278 278 278 278 278
+278 278 278 278 278 278 278 278 278 278 278 278 278 278 278 278
+278 333 556 556 556 556 280 556 333 737 370 556 584 333 737 552
+400 549 333 333 333 576 556 278 333 333 365 556 834 834 834 611
+722 722 722 722 722 722 1000 722 667 667 667 667 278 278 278 278
+722 722 778 778 778 778 778 584 778 722 722 722 722 667 667 611
+556 556 556 556 556 556 889 556 556 556 556 556 278 278 278 278
+611 611 611 611 611 611 611 549 611 611 611 611 611 556 611 556]
+/Encoding 10 0 R
+>>
+endobj
+10 0 obj
+<</Type/Encoding
+/BaseEncoding/WinAnsiEncoding
+/Differences[0/.notdef
+/.notdef
+/.notdef
+128/.notdef
+130/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+142/.notdef
+145/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+/.notdef
+158/.notdef
+/.notdef
+/space
+173/hyphen
+]
+>>
+endobj
+9 0 obj
+<</Type/FontDescriptor
+/Flags 262176
+/Ascent 718
+/CapHeight 718
+/Descent -207
+/FontBBox[-628 -376 2000 1010]
+/FontName/Helvetica-Bold
+/ItalicAngle 0
+/StemV 166
+/XHeight 532
+>>
+endobj
+3 0 obj
+<</Type/Page
+/Parent 2 0 R
+/Contents 4 0 R
+/Resources 7 0 R
+/MediaBox[0 0 612 500]
+>>
+endobj
+2 0 obj
+<</Type/Pages
+/Count 1
+/Kids[ 3 0 R]>>
+endobj
+11 0 obj
+<</Type/Catalog
+/Pages 2 0 R
+>>
+endobj
+xref
+0 12
+0000000000 65535 f 
+0000000015 00000 n 
+0000002385 00000 n 
+0000002284 00000 n 
+0000000063 00000 n 
+0000000348 00000 n 
+0000000537 00000 n 
+0000000367 00000 n 
+0000000422 00000 n 
+0000002093 00000 n 
+0000001708 00000 n 
+0000002439 00000 n 
+trailer
+<</Size 12
+/Root 11 0 R
+/Info 8 0 R
+/ID[<2E2949BF0CCA717C9B1FEA7F231B3F97><2E2949BF0CCA717C9B1FEA7F231B3F97>]
+>>
+startxref
+2487
+%%EOF
diff --git a/spec/textposition.py b/spec/textposition.py
new file mode 100644 (file)
index 0000000..4430716
--- /dev/null
@@ -0,0 +1,54 @@
+from sys import * 
+from pdflib_py import * 
+from math import sin,cos
+p = PDF_new() 
+PDF_open_file(p, "textposition.pdf")
+
+PDF_set_parameter(p, "usercoordinates", "true")
+
+width = 612
+height = 500
+PDF_begin_page(p, width, height)
+
+font = PDF_load_font(p, "Helvetica-Bold", "host", "")
+
+PDF_setfont(p, font, 18.0)
+
+a=0.7
+b=-0.7
+matrices = [[1,0,0,1,100,200],
+            [cos(a),sin(a),-sin(a),cos(a),400,75],
+            [1,0,0,-1,100,350],
+            [-1,0,0,1,450,270],
+            [1.9,0.5,0.6,1.4,50,-140],
+            [cos(b),sin(b),sin(b),-cos(b),100,300],
+            [1.0,0,0,5,-90,-200],
+           ]
+
+for m in matrices:
+    PDF_save(p)
+    PDF_setmatrix(p, m[0],m[1],m[2],m[3],m[4],m[5])
+    x,y = 100,100
+    PDF_set_text_pos(p, x,y)
+    w = PDF_stringwidth(p, "HELLO WORLD", font, 18.0)
+    h = 18.0 - 4
+    PDF_setrgbcolor_fill(p, 0.0, 0.0, 0.0)
+    PDF_show(p, "HELLO WORLD")
+
+    PDF_setrgbcolor_fill(p, 0.0, 0.0, 1.0)
+    PDF_moveto(p, x,y)
+    PDF_lineto(p, x+w,y)
+    PDF_lineto(p, x+w,y+h)
+    PDF_lineto(p, x,y+h)
+    PDF_lineto(p, x,y)
+    PDF_moveto(p, x-20,y-20)
+    PDF_lineto(p, x-20,y+20+h)
+    PDF_lineto(p, x+20+w,y+20+h)
+    PDF_lineto(p, x+20+w,y-20)
+    PDF_lineto(p, x-20,y-20)
+    PDF_fill(p);
+    PDF_restore(p)
+
+PDF_end_page(p)
+PDF_close(p)
+PDF_delete(p);
index f642df6..faa8d1b 100644 (file)
@@ -40,6 +40,8 @@
 
 static gfxsource_t*driver = 0;
 
+static int maxwidth = 0;
+static int maxheight = 0;
 static char * outputname = 0;
 static int loglevel = 3;
 static char * pagerange = 0;
@@ -100,6 +102,16 @@ int args_callback_option(char*name,char*val) {
         free(s);
        return 1;
     }
+    else if (!strcmp(name, "X"))
+    {
+        maxwidth = atoi(val);
+       return 1;
+    }
+    else if (!strcmp(name, "Y"))
+    {
+        maxheight = atoi(val);
+       return 1;
+    }
     else if (!strcmp(name, "V"))
     {  
        printf("pdf2swf - part of %s %s\n", PACKAGE, VERSION);
@@ -193,7 +205,7 @@ int main(int argn, char *argv[])
     }
 
     gfxdocument_t* doc = driver->open(driver, filename);
-    doc->set_parameter(doc, "drawonlyshapes", "1");
+    //doc->set_parameter(doc, "drawonlyshapes", "1");
     doc->set_parameter(doc, "disable_polygon_conversion", "1");
 
     if(!doc) {
@@ -208,6 +220,13 @@ int main(int argn, char *argv[])
     gfxdevice_removeclippings_init(&wrap, out);
     out = &wrap;*/
 
+    gfxdevice_t rescale;
+    if(maxwidth || maxheight) {
+        gfxdevice_rescale_init(&rescale, out, maxwidth, maxheight, 0);
+        out = &rescale;
+        out->setparameter(out, "keepratio", "1");
+    }
+
     int pagenr;
     for(pagenr = 1; pagenr <= doc->num_pages; pagenr++) 
     {