From 0e916263b32f4920c2f5581caa77985bf1992081 Mon Sep 17 00:00:00 2001 From: kramm Date: Fri, 23 Nov 2001 15:59:18 +0000 Subject: [PATCH] added support for truetype libs using ttf2pt1. --- pdf2swf/SWFOutputDev.cc | 154 +++++++++++++++++++++++++++++++++++++---------- pdf2swf/swfoutput.cc | 67 ++++++++++++++------- pdf2swf/swfoutput.h | 7 ++- 3 files changed, 171 insertions(+), 57 deletions(-) diff --git a/pdf2swf/SWFOutputDev.cc b/pdf2swf/SWFOutputDev.cc index e32a293..5d53fbd 100644 --- a/pdf2swf/SWFOutputDev.cc +++ b/pdf2swf/SWFOutputDev.cc @@ -44,6 +44,7 @@ #include "swfoutput.h" extern "C" { #include "../lib/log.h" +#include "ttf2pt1.h" } static PDFDoc*doc = 0; @@ -189,12 +190,14 @@ public: int clipping[64]; int clippos; - int setT1Font(char*name,FontEncoding*enc); - char* substitutefont(GfxFont*gfxFont); + int searchT1Font(char*name); + char* substituteFont(GfxFont*gfxFont, char*oldname); + char* writeEmbeddedFontToFile(GfxFont*font); int t1id; int jpeginfo; // did we write "File contains jpegs" yet? int pbminfo; // did we write "File contains jpegs" yet? int linkinfo; // did we write "File contains links" yet? + int ttfinfo; // did we write "File contains TrueType Fonts" yet? GfxState *laststate; }; @@ -330,7 +333,6 @@ void showFontError(GfxFont*font, int nr) logf(" The following font caused problems (substituting):"); else if(nr == 2) logf(" This document contains Type 3 Fonts: (some text may be incorrectly displayed)"); - dumpFontInfo("", font); } @@ -393,6 +395,7 @@ void dumpFontInfo(char*loglevel, GfxFont*font) SWFOutputDev::SWFOutputDev() { jpeginfo = 0; + ttfinfo = 0; linkinfo = 0; pbminfo = 0; clippos = 0; @@ -562,7 +565,7 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, double dx, doub state->transform(x, y, &x1, &y1); if(enc->getCharName(c)) - swfoutput_drawchar(&output, x1, y1, enc->getCharName(c)); + swfoutput_drawchar(&output, x1, y1, enc->getCharName(c), c); else logf(" couldn't get name for character %02x from Encoding", c); } @@ -754,7 +757,7 @@ void SWFOutputDev::restoreState(GfxState *state) { char type3Warning=0; -int SWFOutputDev::setT1Font(char*name, FontEncoding*encoding) +int SWFOutputDev::searchT1Font(char*name) { int i; @@ -779,11 +782,7 @@ int SWFOutputDev::setT1Font(char*name, FontEncoding*encoding) pdf2t1map[i].id = mapid; } } - if(id<0) - return 0; - - this->t1id = id; - return 1; + return id; } void SWFOutputDev::updateLineWidth(GfxState *state) @@ -812,10 +811,9 @@ void SWFOutputDev::updateStrokeColor(GfxState *state) (char)(rgb.b*255), (char)(opaq*255)); } -char*writeEmbeddedFontToFile(GfxFont*font) +char*SWFOutputDev::writeEmbeddedFontToFile(GfxFont*font) { char*tmpFileName = NULL; - char*fileName = NULL; FILE *f; int c; char *fontBuf; @@ -854,12 +852,26 @@ char*writeEmbeddedFontToFile(GfxFont*font) strObj.free(); } fclose(f); - fileName = tmpFileName; - if(!fileName) { - logf(" Embedded font writer didn't create a file"); - return 0; + + if(font->getType() == fontTrueType) + { + if(!ttfinfo) { + logf(" File contains TrueType fonts"); + ttfinfo = 1; + } + char name2[80]; + int r1 = lrand48(); + int r2 = lrand48(); + sprintf(name2,"%04x%04x",r1,r2); + char*a[] = {"./ttf2pt1","-pttf","-b", tmpFileName, name2}; + logf(" Invoking ttf2pt1..."); + ttf2pt1_main(5,a); + unlink(tmpFileName); + sprintf(name2,"%04x%04x.pfb",r1,r2); + tmpFileName = strdup(name2); } - return fileName; + + return tmpFileName; } char* gfxFontName(GfxFont* gfxFont) @@ -877,7 +889,11 @@ char* gfxFontName(GfxFont* gfxFont) } } -char* SWFOutputDev::substitutefont(GfxFont*gfxFont) +char* substitutetarget[256]; +char* substitutesource[256]; +int substitutepos = 0; + +char* SWFOutputDev::substituteFont(GfxFont*gfxFont, char* oldname) { //substitute font char* fontname = 0; @@ -950,28 +966,70 @@ char* SWFOutputDev::substitutefont(GfxFont*gfxFont) } } } - if(fontname) - setT1Font(fontname, gfxFont->getEncoding()); + if(fontname) { + this->t1id = searchT1Font(fontname); + } + if(substitutepos>=sizeof(substitutesource)/sizeof(char*)) { + logf(" Too many fonts in file."); + exit(1); + } + substitutesource[substitutepos] = oldname; + substitutetarget[substitutepos] = fontname; + logf(" substituting %s -> %s", oldname, fontname); + substitutepos ++; return fontname; } +void unlinkfont(char* filename) +{ + int l; + if(!filename) + return; + l=strlen(filename); + unlink(filename); + if(!strncmp(&filename[l-4],".afm",4)) { + memcpy(&filename[l-4],".pfb",4); + unlink(filename); + memcpy(&filename[l-4],".pfa",4); + unlink(filename); + memcpy(&filename[l-4],".afm",4); + return; + } else + if(!strncmp(&filename[l-4],".pfa",4)) { + memcpy(&filename[l-4],".afm",4); + unlink(filename); + memcpy(&filename[l-4],".pfa",4); + return; + } else + if(!strncmp(&filename[l-4],".pfb",4)) { + memcpy(&filename[l-4],".afm",4); + unlink(filename); + memcpy(&filename[l-4],".pfb",4); + return; + } +} + void SWFOutputDev::updateFont(GfxState *state) { - char * fontname = 0; GfxFont*gfxFont = state->getFont(); char * fileName = 0; if (!gfxFont) { return; } - - if(gfxFont->getName()) { - fontname = gfxFont->getName()->getCString(); + char * fontname = gfxFontName(gfxFont); + + int t; + for(t=0;tis16Bit() && (gfxFont->getType() == fontType1 || - gfxFont->getType() == fontType1C)) { + gfxFont->getType() == fontType1C || + gfxFont->getType() == fontTrueType)) { fileName = writeEmbeddedFontToFile(gfxFont); - if(!fileName) + if(!fileName) { + logf(" Couldn't write font to file"); + showFontError(gfxFont,0); return ; + } this->t1id = T1_AddFont(fileName); + if(this->t1id<0) { + logf(" Couldn't load font from file"); + showFontError(gfxFont,0); + unlinkfont(fileName); + return ; + } } else { showFontError(gfxFont,0); - fontname = substitutefont(gfxFont); + fontname = substituteFont(gfxFont, fontname); } } else { - if(!fontname || !setT1Font(state->getFont()->getName()->getCString(), gfxFont->getEncoding())) - fontname = substitutefont(gfxFont); + if(fontname) { + int newt1id = searchT1Font(fontname); + if(newt1id<0) { + fontname = substituteFont(gfxFont, fontname); + } else + this->t1id = newt1id; + } + else + fontname = substituteFont(gfxFont, fontname); + } + + if(t1id<0) { + showFontError(gfxFont,0); + } + + /* we may have done some substitutions here, so check + again if this font is cached. */ + if(swfoutput_queryfont(&output, fontname)) + { + swfoutput_setfont(&output, fontname, -1, 0); + return; } - swfoutput_setfont(&output,gfxFontName(gfxFont),this->t1id, fileName); + logf(" Creating new SWF font: t1id: %d, filename: %s name:%s", this->t1id, fileName, fontname); + swfoutput_setfont(&output, fontname, this->t1id, fileName); if(fileName) - unlink(fileName); + unlinkfont(fileName); } int pic_xids[1024]; diff --git a/pdf2swf/swfoutput.cc b/pdf2swf/swfoutput.cc index f84ebee..74c982d 100644 --- a/pdf2swf/swfoutput.cc +++ b/pdf2swf/swfoutput.cc @@ -421,7 +421,7 @@ void putcharacter(struct swfoutput*obj, int fontid, int charid, /* process a character. */ -void drawchar(struct swfoutput*obj, SWFFont*font, char*character, swfmatrix*m) +void drawchar(struct swfoutput*obj, SWFFont*font, char*character, int charnr, swfmatrix*m) { int usefonts=1; if(m->m12!=0 || m->m21!=0) @@ -431,7 +431,7 @@ void drawchar(struct swfoutput*obj, SWFFont*font, char*character, swfmatrix*m) if(usefonts && ! drawonlyshapes) { - int charid = font->getSWFCharID(character); + int charid = font->getSWFCharID(character, charnr); if(shapeid>=0) endshape(); if(textid<0) @@ -505,32 +505,45 @@ SWFFont::SWFFont(char*name, int id, char*filename) this->name = strdup(T1_GetFontFileName(id)); this->fontid = strdup(name); this->t1id = id; - + char**a= T1_GetAllCharNames(id); - int t=0, outlinepos=0; + int t, outlinepos=0; char*map[256]; + + t=0; while(a[t]) t++; - this->charnum = t; - if(!t) + + if(!charnum) return; - logf(" Font %s(%d): Storing %d outlines.\n", name, id, t); + logf(" Font %s(%d): Storing %d outlines.\n", name, id, charnum); + + this->standardtablesize = 256; + if(this->charnum < this->standardtablesize) + this->standardtablesize = this->charnum; + this->standardtable = (char**)malloc(standardtablesize*sizeof(char*)); + + for(t = 0; t < this->standardtablesize; t++) { + char*name = T1_GetCharName(id,t); + if(!name) + name = ""; + standardtable[t] = strdup(name); + } - outline = (T1_OUTLINE**)malloc(t*sizeof(T1_OUTLINE*)); - charname = (char**)malloc(t*sizeof(char*)); - width = (int*)malloc(t*sizeof(int)); - memset(width, 0, t*sizeof(int)); - memset(charname, 0, t*sizeof(char*)); - used = (char*)malloc(t*sizeof(char)); - char2swfcharid = (U16*)malloc(t*2); - swfcharid2char = (U16*)malloc(t*2); + outline = (T1_OUTLINE**)malloc(charnum*sizeof(T1_OUTLINE*)); + charname = (char**)malloc(charnum*sizeof(char*)); + width = (int*)malloc(charnum*sizeof(int)); + memset(width, 0, charnum*sizeof(int)); + memset(charname, 0, charnum*sizeof(char*)); + used = (char*)malloc(charnum*sizeof(char)); + char2swfcharid = (U16*)malloc(charnum*2); + swfcharid2char = (U16*)malloc(charnum*2); swfcharpos = 0; - memset(used,0,t*sizeof(char)); + memset(used,0,charnum*sizeof(char)); this->swfid = ++currentswfid; - t=0; while(*a) @@ -555,9 +568,11 @@ SWFFont::SWFFont(char*name, int id, char*filename) // parsecharacters for(s=0;soutline[outlinepos] = T1_CopyOutline(T1_GetCharOutline(id, s, 100.0, 0)); this->width[outlinepos] = T1_GetCharWidth(id, s); - this->charname[outlinepos] = strdup(T1_GetCharName(id, s)); + this->charname[outlinepos] = strdup(name); outlinepos++; } t=0; @@ -577,7 +592,7 @@ SWFFont::~SWFFont() for(t=0;tcharnum;t++) { if(this->charname[t]) - getSWFCharID(this->charname[t]); + getSWFCharID(this->charname[t], -1); } } @@ -647,6 +662,11 @@ SWFFont::~SWFFont() free(outline); for(t=0;tcharnum;t++) { @@ -686,6 +706,9 @@ int SWFFont::getSWFCharID(char*name) return char2swfcharid[t]; } } + if(this->standardtable && charnr>=0 && charnr < this->standardtablesize) { + return getSWFCharID(this->standardtable[charnr], -1); + } logf(" Didn't find character '%s' in font '%s'", name, this->name); return 0; } @@ -767,7 +790,7 @@ void swfoutput_setfontmatrix(struct swfoutput*obj,double m11,double m12, } /* draws a character at x,y. */ -void swfoutput_drawchar(struct swfoutput* obj,double x,double y,char*character) +void swfoutput_drawchar(struct swfoutput* obj,double x,double y,char*character, int charnr) { swfmatrix m; m.m11 = obj->fontm11; @@ -776,7 +799,7 @@ void swfoutput_drawchar(struct swfoutput* obj,double x,double y,char*character) m.m22 = obj->fontm22; m.m13 = x; m.m23 = y; - drawchar(obj, obj->font, character, &m); + drawchar(obj, obj->font, character, charnr, &m); } /* initialize the swf writer */ diff --git a/pdf2swf/swfoutput.h b/pdf2swf/swfoutput.h index 530d11c..1efc9cc 100644 --- a/pdf2swf/swfoutput.h +++ b/pdf2swf/swfoutput.h @@ -46,6 +46,9 @@ class SWFFont U16*swfcharid2char; int swfcharpos; + char**standardtable; + int standardtablesize; + public: int t1id; @@ -55,7 +58,7 @@ class SWFFont SWFFont(char*name, int t1id, char*filename); SWFFont::~SWFFont(); T1_OUTLINE*getOutline(char*charname); - int getSWFCharID(char*name); + int getSWFCharID(char*name, int charnr); char*getName(); char*getCharName(int t); int getCharWidth(int t) {return width[t];} @@ -90,7 +93,7 @@ void swfoutput_setstrokecolor(struct swfoutput*, unsigned char r, unsigned char void swfoutput_setfontmatrix(struct swfoutput*,double,double,double,double); void swfoutput_setlinewidth(struct swfoutput*, double linewidth); -void swfoutput_drawchar(struct swfoutput*,double x,double y,char*a); +void swfoutput_drawchar(struct swfoutput*,double x,double y,char*a, int charnr); void swfoutput_drawpath(struct swfoutput*, T1_OUTLINE*outline, struct swfmatrix*m); void swfoutput_startclip(struct swfoutput*, T1_OUTLINE*outline, struct swfmatrix*m); void swfoutput_endclip(struct swfoutput*); -- 1.7.10.4