From: kramm Date: Thu, 18 Oct 2001 20:36:17 +0000 (+0000) Subject: implemented two levels of font cache X-Git-Tag: release-0-0-2~46 X-Git-Url: http://git.asbjorn.it/?a=commitdiff_plain;h=c42167873a57926d413c9ee3c90119fae729cce5;p=swftools.git implemented two levels of font cache --- diff --git a/pdf2swf/SWFOutputDev.cc b/pdf2swf/SWFOutputDev.cc index 7563762..b2573d8 100644 --- a/pdf2swf/SWFOutputDev.cc +++ b/pdf2swf/SWFOutputDev.cc @@ -393,9 +393,12 @@ void dumpFontInfo(char*loglevel, GfxFont*font) logf("%sType: TrueType\n",loglevel); break; } + + Ref embRef; + GBool embedded = font->getEmbeddedFontID(&embRef); name = font->getEmbeddedFontName(); - if(name) - logf("%sEmbedded name: %s\n",loglevel, name); + if(embedded) + logf("%sEmbedded name: %s id: %d\n",loglevel, name, embRef.num); gstr = font->getExtFontFile(); if(gstr) @@ -722,6 +725,10 @@ int SWFOutputDev::setT1Font(char*name, FontEncoding*encoding) if(id<0) return 0; + /* T1 allows us to recode only once. Therefore, remove + and reload the font to reset it */ + T1_DeleteFont(id); + T1_LoadFont(id); initT1Font(id, encoding); } @@ -730,8 +737,10 @@ int SWFOutputDev::initT1Font(int id, FontEncoding*encoding) int encStrSize; char *encPtr; int i; - T1_DeleteFont(id); - T1_LoadFont(id); + + if(!T1_GetFontName(id)) + T1_LoadFont(id); + /* reencode the font: * This is the only way to get the unmapped characters * from t1lib @@ -789,58 +798,37 @@ void SWFOutputDev::updateStrokeColor(GfxState *state) (char)(rgb.b*255), (char)(opaq*255)); } -void SWFOutputDev::updateFont(GfxState *state) +char*writeEmbeddedFontToFile(GfxFont*font) { - double m11, m12, m21, m22; - char * fontname = 0; - GfxFont*gfxFont = state->getFont(); - char * filename; - - if (!gfxFont) { - return; - } - // look for Type 3 font - if (!type3Warning && gfxFont->getType() == fontType3) { - type3Warning = gTrue; - showFontError(gfxFont, 2); - } - //dumpFontInfo (gfxFont); - - - Ref embRef; - GBool embedded = gfxFont->getEmbeddedFontID(&embRef); - if(embedded) { - char*tmpFileName = NULL; - char*fileName = NULL; - FILE *f; - char *fontBuf; - int fontLen; - Type1CFontConverter *cvt; - Ref embRef; - Object refObj, strObj; - int c; - if (!gfxFont->is16Bit() && - (gfxFont->getType() == fontType1 || - gfxFont->getType() == fontType1C) && - gfxFont->getEmbeddedFontID(&embRef)) { + char*tmpFileName = NULL; + char*fileName = NULL; + FILE *f; + int c; + char *fontBuf; + int fontLen; + Type1CFontConverter *cvt; + Ref embRef; + Object refObj, strObj; tmpFileName = "tmpfont"; + font->getEmbeddedFontID(&embRef); + f = fopen(tmpFileName, "wb"); if (!f) { logf(" Couldn't create temporary Type 1 font file"); - return; + return 0; } - if (gfxFont->getType() == fontType1C) { - if (!(fontBuf = gfxFont->readEmbFontFile(&fontLen))) { + if (font->getType() == fontType1C) { + if (!(fontBuf = font->readEmbFontFile(&fontLen))) { fclose(f); logf(" Couldn't read embedded font file"); - return ; + return 0; } cvt = new Type1CFontConverter(fontBuf, fontLen, f); cvt->convert(); delete cvt; gfree(fontBuf); } else { - gfxFont->getEmbeddedFontID(&embRef); + font->getEmbeddedFontID(&embRef); refObj.initRef(embRef.num, embRef.gen); refObj.fetch(&strObj); refObj.free(); @@ -855,14 +843,71 @@ void SWFOutputDev::updateFont(GfxState *state) fileName = tmpFileName; if(!fileName) { logf(" Embedded font writer didn't create a file"); - return ; + return 0; } + return fileName; +} + +int embeddedids[128]; +int embeddedt1ids[128]; +int embedded_mappos = 0; +int embedded_maxpos = 128; + +void SWFOutputDev::updateFont(GfxState *state) +{ + double m11, m12, m21, m22; + char * fontname = 0; + GfxFont*gfxFont = state->getFont(); + + if (!gfxFont) { + return; + } + + if(swfoutput_queryfont(&output, gfxFont->getID().num)) + { + swfoutput_setfont(&output, gfxFont->getID().num, -1); + return; + } + + // look for Type 3 font + if (!type3Warning && gfxFont->getType() == fontType3) { + type3Warning = gTrue; + showFontError(gfxFont, 2); + } + //dumpFontInfo ("", gfxFont); + + Ref embRef; + GBool embedded = gfxFont->getEmbeddedFontID(&embRef); + if(embedded) { + int t; + for(t=0;tis16Bit() && + (gfxFont->getType() == fontType1 || + gfxFont->getType() == fontType1C)) { + + fileName = writeEmbeddedFontToFile(gfxFont); + if(!fileName) + return ; + } + else { + showFontError(gfxFont,0); + return ; + } + t1id = T1_AddFont(fileName); + embeddedids[embedded_mappos] = embRef.num; + embeddedt1ids[embedded_mappos] = t1id; + if(embedded_mappos < embedded_maxpos-1) + embedded_mappos++; } - else { - showFontError(gfxFont,0); - return ; + else + { + t1id = embeddedt1ids[t]; } - t1id = T1_AddFont(fileName); initT1Font(t1id, gfxFont->getEncoding()); } else { fontname = NULL; diff --git a/pdf2swf/swfoutput.cc b/pdf2swf/swfoutput.cc index cb8e8f8..2993ffc 100644 --- a/pdf2swf/swfoutput.cc +++ b/pdf2swf/swfoutput.cc @@ -195,28 +195,26 @@ void drawpath(T1_OUTLINE*outline, struct swfmatrix*m, char*namehint) outline = outline->link; } } + //logf(" Font name is %s", T1_GetFontFileName(t1fontindex)); + //logf(" char 0x%02x is named %s\n",character,charname); + //logf(" bbox: %d %d %d %d\n",bbox.llx,bbox.lly,bbox.urx,bbox.ury); + //char*charname = T1_GetCharName(t1fontindex, character); /* process a character. */ -void drawchar(struct swfoutput*obj, int t1fontindex, char character, swfmatrix*m) -{ - - /* */ - T1_OUTLINE*outline; - int width = T1_GetCharWidth(t1fontindex, character); - BBox bbox = T1_GetCharBBox(t1fontindex, character); - char*charname= T1_GetCharName(t1fontindex, character); - logf(" Font name is %s", T1_GetFontFileName(t1fontindex)); - logf(" char 0x%02x is named %s\n",character,charname); - logf(" bbox: %d %d %d %d\n",bbox.llx,bbox.lly,bbox.urx,bbox.ury); - if(!charname || charname[0] == '.') +void drawchar(struct swfoutput*obj, SWFFont*font, char character, swfmatrix*m) +{ + T1_OUTLINE*outline = font->getOutline(character); + char* charname = font->getCharName(character); + + if(!outline) { /* for newline, we don't print an error. FIXME: We shouldn't get newlines here in the first place */ if(character != '\n') { logf(" Char to set is not defined!"); - logf(" - font file is %s\n", T1_GetFontFileName(t1fontindex)); - logf(" - char 0x%02x is named %s\n",character,charname); + logf(" - font file is %s\n", font->getName()); + logf(" - char 0x%02x is named %s\n",character, charname); } return; } @@ -225,9 +223,6 @@ void drawchar(struct swfoutput*obj, int t1fontindex, char character, swfmatrix*m m2.m21/=100; m2.m12/=100; m2.m22/=100; - outline = T1_GetCharOutline( t1fontindex, character, 100.0, 0); - - /** **/ if(shapeid<0) startshape(obj); @@ -259,11 +254,96 @@ void swfoutput_drawpath(swfoutput*output, T1_OUTLINE*outline, struct swfmatrix*m drawpath(outline,m, 0); } +SWFFont::SWFFont(int t1fontindex) +{ + int t; + for(t=0;t<256;t++) + { + int width = T1_GetCharWidth(t1fontindex, t); + BBox bbox = T1_GetCharBBox(t1fontindex, t); + T1_OUTLINE*outline = T1_GetCharOutline(t1fontindex,t,100.0,0); + + char*name; + this->outline[t] = T1_CopyOutline(outline); + + name = T1_GetCharName(t1fontindex, t); + if(!name || name[0]=='.') + { + this->charname[t] = 0; + this->outline[t] = 0; + } + else + this->charname[t] = strdup(name); + } + this->name = strdup(T1_GetFontFileName(t1fontindex)); +} + +T1_OUTLINE*SWFFont::getOutline(unsigned char nr) +{ + return outline[nr]; +} + +char*SWFFont::getCharName(int t) +{ + return this->charname[t]; +} + +char*SWFFont::getName() +{ + return this->name; +} + +struct fontlist_t +{ + SWFFont * font; + fontlist_t*next; +} *fontlist = 0; /* set's the t1 font index of the font to use for swfoutput_drawchar(). */ -int swfoutput_setfont(struct swfoutput*obj, int fontid, int t1id) +void swfoutput_setfont(struct swfoutput*obj, int fontid, int t1id) { - obj->t1font = t1id; + fontlist_t*last=0,*iterator; + if(obj->font && obj->font->id == fontid) + return; + + iterator = fontlist; + while(iterator) { + if(iterator->font->id == fontid) + break; + last = iterator; + iterator = iterator->next; + } + if(iterator) + { + obj->font = iterator->font; + return ; + } + + if(t1id<0) { + logf(" internal error: t1id:%d, fontid:%d\n", t1id,fontid); + } + + SWFFont*font = new SWFFont(t1id); + iterator = new fontlist_t; + iterator->font = font; + iterator->next = 0; + + if(last) + last->next = iterator; + else + fontlist = iterator; + obj->font = font; +} + +int swfoutput_queryfont(struct swfoutput*obj, int fontid) +{ + fontlist_t *iterator = fontlist; + while(iterator) { + if(iterator->font->id == fontid) + return 1; + iterator = iterator->next; + } + return 0; } /* set's the matrix which is to be applied to characters drawn by @@ -287,7 +367,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->t1font, character, &m); + drawchar(obj, obj->font, character, &m); } /* initialize the swf writer */ @@ -303,7 +383,7 @@ void swfoutput_init(struct swfoutput* obj, char*_filename, int _sizex, int _size logf(" initializing swf output for size %d*%d\n", sizex,sizey); - obj->t1font = 0; + obj->font = 0; memset(&swf,0x00,sizeof(SWF)); diff --git a/pdf2swf/swfoutput.h b/pdf2swf/swfoutput.h index 6583015..8db8f3a 100644 --- a/pdf2swf/swfoutput.h +++ b/pdf2swf/swfoutput.h @@ -26,11 +26,28 @@ struct swfcoord { twip y; }; +class SWFFont +{ + T1_OUTLINE*(outline[256]); + char*(charname[256]); + char*name; + + public: + + int id; + + SWFFont(int t1id); + T1_OUTLINE*getOutline(unsigned char nr); + char*getName(); + char*getCharName(int t); +}; + struct swfoutput { - int t1font; + //int t1font; double fontm11,fontm12,fontm21,fontm22; unsigned short int linewidth; + SWFFont*font; RGBA strokergb; RGBA fillrgb; }; @@ -46,7 +63,8 @@ void swfoutput_setprotected(); //write PROTECT tag void swfoutput_newpage(struct swfoutput*); - int swfoutput_setfont(struct swfoutput*, int fontid, int t1font); +void swfoutput_setfont(struct swfoutput*, int fontid, int t1font); +int swfoutput_queryfont(struct swfoutput*, int fontid); void swfoutput_setdrawmode(struct swfoutput*, int drawmode); void swfoutput_setfillcolor(struct swfoutput*, unsigned char r, unsigned char g, unsigned char b, unsigned char a); void swfoutput_setstrokecolor(struct swfoutput*, unsigned char r, unsigned char g, unsigned char b, unsigned char a);