From 0e9d27093c3e6e8e316fbc08bb9d422d74da2fd1 Mon Sep 17 00:00:00 2001 From: kramm Date: Tue, 18 Aug 2009 17:23:00 +0200 Subject: [PATCH] implemented type3 fonts in pdf2pdf, added fontmatrix tests to testsuite --- config.h.in | 9 --- configure.in | 3 - lib/devices/pdf.c | 73 +++++++++++++++++++++---- lib/gfxpoly.c | 6 -- lib/gfxtools.c | 18 +++++- lib/gfxtools.h | 3 + spec/textposition.pdf | 146 +++++++++++++++++++++++++++++++++++++++++++++++++ spec/textposition.py | 54 ++++++++++++++++++ src/pdf2pdf.c | 21 ++++++- 9 files changed, 301 insertions(+), 32 deletions(-) create mode 100644 spec/textposition.pdf create mode 100644 spec/textposition.py diff --git a/config.h.in b/config.h.in index e91ada7..c486e83 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 header file. */ -#undef HAVE_LIBART_LGPL_LIBART_H - /* Name of package */ #undef PACKAGE diff --git a/configure.in b/configure.in index 5dae635..b3adafb 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 ba92ed0..4d223c8 100644 --- a/lib/devices/pdf.c +++ b/lib/devices/pdf.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -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;tp, 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;tglyphs[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 902eaf8..dd97ff4 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 -#include -#include -#endif #include "log.h" #include #include diff --git a/lib/gfxtools.c b/lib/gfxtools.c index 9975e6d..d8aef3f 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 163138b..ff282a3 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 0000000..44743b7 --- /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 +<> +stream +xœÕTÍ ¾÷)zÔ 6¸g<,@3³æû,?ºèR íW’æûÊ-‰RTd·D +½°°;RÒb!î",Z¸ÃæÔ{?àu¸øÃ6> +>> +endobj +8 0 obj +<> +endobj +6 0 obj +<> +endobj +10 0 obj +<> +endobj +9 0 obj +<> +endobj +3 0 obj +<> +endobj +2 0 obj +<> +endobj +11 0 obj +<> +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 +<<2E2949BF0CCA717C9B1FEA7F231B3F97>] +>> +startxref +2487 +%%EOF diff --git a/spec/textposition.py b/spec/textposition.py new file mode 100644 index 0000000..4430716 --- /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 f642df6..faa8d1b 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++) { -- 1.7.10.4