diff options
-rw-r--r-- | config.h.in | 9 | ||||
-rw-r--r-- | configure.in | 3 | ||||
-rw-r--r-- | lib/devices/pdf.c | 73 | ||||
-rw-r--r-- | lib/gfxpoly.c | 6 | ||||
-rw-r--r-- | lib/gfxtools.c | 18 | ||||
-rw-r--r-- | lib/gfxtools.h | 3 | ||||
-rw-r--r-- | spec/textposition.pdf | 146 | ||||
-rw-r--r-- | spec/textposition.py | 54 | ||||
-rw-r--r-- | src/pdf2pdf.c | 21 |
9 files changed, 301 insertions, 32 deletions
diff --git a/config.h.in b/config.h.in index e91ada77..c486e835 100644 --- a/config.h.in +++ b/config.h.in @@ -178,15 +178,6 @@ /* 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 diff --git a/configure.in b/configure.in index 5dae635e..b3adafb1 100644 --- a/configure.in +++ b/configure.in @@ -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]) diff --git a/lib/devices/pdf.c b/lib/devices/pdf.c index ba92ed0c..4d223c8d 100644 --- a/lib/devices/pdf.c +++ b/lib/devices/pdf.c @@ -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; } diff --git a/lib/gfxpoly.c b/lib/gfxpoly.c index 902eaf88..dd97ff43 100644 --- a/lib/gfxpoly.c +++ b/lib/gfxpoly.c @@ -25,15 +25,9 @@ #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> diff --git a/lib/gfxtools.c b/lib/gfxtools.c index 9975e6d2..d8aef3f0 100644 --- a/lib/gfxtools.c +++ b/lib/gfxtools.c @@ -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; diff --git a/lib/gfxtools.h b/lib/gfxtools.h index 163138b4..ff282a39 100644 --- a/lib/gfxtools.h +++ b/lib/gfxtools.h @@ -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 index 00000000..44743b72 --- /dev/null +++ b/spec/textposition.pdf @@ -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 +xT )z6g<,@3,?RW-RTdD +;Rb!",Z{?u6<!Ce}fPMÝSɛVOjj%hcm)eJɏgW#aV[Z!+gjz3wybLhNS)DѡMHQ7Fē&2G\"$ +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 index 00000000..4430716f --- /dev/null +++ b/spec/textposition.py @@ -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); diff --git a/src/pdf2pdf.c b/src/pdf2pdf.c index f642df6a..faa8d1b6 100644 --- a/src/pdf2pdf.c +++ b/src/pdf2pdf.c @@ -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++) { |