#include "swfoutput.h"
extern "C" {
#include "../lib/log.h"
+#include "ttf2pt1.h"
}
static PDFDoc*doc = 0;
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;
};
logf("<warning> The following font caused problems (substituting):");
else if(nr == 2)
logf("<warning> This document contains Type 3 Fonts: (some text may be incorrectly displayed)");
-
dumpFontInfo("<warning>", font);
}
SWFOutputDev::SWFOutputDev()
{
jpeginfo = 0;
+ ttfinfo = 0;
linkinfo = 0;
pbminfo = 0;
clippos = 0;
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("<warning> couldn't get name for character %02x from Encoding", c);
}
char type3Warning=0;
-int SWFOutputDev::setT1Font(char*name, FontEncoding*encoding)
+int SWFOutputDev::searchT1Font(char*name)
{
int i;
pdf2t1map[i].id = mapid;
}
}
- if(id<0)
- return 0;
-
- this->t1id = id;
- return 1;
+ return id;
}
void SWFOutputDev::updateLineWidth(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;
strObj.free();
}
fclose(f);
- fileName = tmpFileName;
- if(!fileName) {
- logf("<error> Embedded font writer didn't create a file");
- return 0;
+
+ if(font->getType() == fontTrueType)
+ {
+ if(!ttfinfo) {
+ logf("<notice> 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("<verbose> 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)
}
}
-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;
}
}
}
- if(fontname)
- setT1Font(fontname, gfxFont->getEncoding());
+ if(fontname) {
+ this->t1id = searchT1Font(fontname);
+ }
+ if(substitutepos>=sizeof(substitutesource)/sizeof(char*)) {
+ logf("<fatal> Too many fonts in file.");
+ exit(1);
+ }
+ substitutesource[substitutepos] = oldname;
+ substitutetarget[substitutepos] = fontname;
+ logf("<verbose> 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;t<substitutepos;t++) {
+ if(!strcmp(fontname, substitutesource[t])) {
+ fontname = substitutetarget[t];
+ break;
+ }
}
- if(swfoutput_queryfont(&output, gfxFontName(gfxFont)))
+ if(swfoutput_queryfont(&output, fontname))
{
- swfoutput_setfont(&output, gfxFontName(gfxFont), -1, 0);
+ swfoutput_setfont(&output, fontname, -1, 0);
return;
}
if(embedded) {
if (!gfxFont->is16Bit() &&
(gfxFont->getType() == fontType1 ||
- gfxFont->getType() == fontType1C)) {
+ gfxFont->getType() == fontType1C ||
+ gfxFont->getType() == fontTrueType)) {
fileName = writeEmbeddedFontToFile(gfxFont);
- if(!fileName)
+ if(!fileName) {
+ logf("<error> Couldn't write font to file");
+ showFontError(gfxFont,0);
return ;
+ }
this->t1id = T1_AddFont(fileName);
+ if(this->t1id<0) {
+ logf("<error> 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("<verbose> 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];
/* 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)
if(usefonts && ! drawonlyshapes)
{
- int charid = font->getSWFCharID(character);
+ int charid = font->getSWFCharID(character, charnr);
if(shapeid>=0)
endshape();
if(textid<0)
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("<verbose> Font %s(%d): Storing %d outlines.\n", name, id, t);
+ logf("<verbose> 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)
// parsecharacters
for(s=0;s<t;s++)
{
+ char* name = T1_GetCharName(id, s);
+ if(!name) name = "";
this->outline[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;
for(t=0;t<this->charnum;t++)
{
if(this->charname[t])
- getSWFCharID(this->charname[t]);
+ getSWFCharID(this->charname[t], -1);
}
}
free(outline);
for(t=0;t<charnum;t++)
free(charname[t]);
+ for(t=0;t<standardtablesize;t++)
+ if(standardtable[t]) {
+ free(standardtable[t]);
+ }
+ free(standardtable);
free(charname);
free(width);
free(used);
return 0;
}
-int SWFFont::getSWFCharID(char*name)
+int SWFFont::getSWFCharID(char*name, int charnr)
{
int t;
for(t=0;t<this->charnum;t++) {
return char2swfcharid[t];
}
}
+ if(this->standardtable && charnr>=0 && charnr < this->standardtablesize) {
+ return getSWFCharID(this->standardtable[charnr], -1);
+ }
logf("<warning> Didn't find character '%s' in font '%s'", name, this->name);
return 0;
}
}
/* 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;
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 */