/* config */
static double caplinewidth = 3.0;
static int zoom = 72; /* xpdf: 86 */
-static int forceType0Fonts = 0;
+static int forceType0Fonts = 1;
static void printInfoString(Dict *infoDict, char *key, char *fmt);
static void printInfoDate(Dict *infoDict, char *key, char *fmt);
{"Symbol", "s050000l"},
{"ZapfDingbats", "d050000l"}};
+class SWFOutputState {
+ public:
+ int clipping;
+ int textRender;
+ SWFOutputState() {
+ this->clipping = 0;
+ this->textRender = 0;
+ }
+};
+
class SWFOutputDev: public OutputDev {
int outputstarted;
struct swfoutput output;
//----- text drawing
virtual void beginString(GfxState *state, GString *s) ;
virtual void endString(GfxState *state) ;
+ virtual void endTextObject(GfxState *state);
virtual void drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
void drawGeneralImage(GfxState *state, Object *ref, Stream *str,
int width, int height, GfxImageColorMap*colorMap, GBool invert,
GBool inlineImg, int mask, int *maskColors);
- int clipping[64];
- int clippos;
+ SWFOutputState states[64];
+ int statepos;
int currentpage;
GfxFont*font = state->getFont();
if(!font)
return;
- char*id = getFontID(font);
+ /*char*id = getFontID(font);*/
/* FIXME*/
num_fonts++;
}
linkinfo = 0;
pbminfo = 0;
type3active = 0;
- clippos = 0;
- clipping[clippos] = 0;
+ statepos = 0;
outputstarted = 0;
xref = 0;
substitutepos = 0;
static void dumpFontInfo(char*loglevel, GfxFont*font)
{
- char* name = getFontID(font);
+ char* id = getFontID(font);
+ char* name = getFontName(font);
Ref* r=font->getID();
- msg("%s=========== %s (ID:%d,%d) ==========\n", loglevel, getFontName(font), r->num,r->gen);
+ msg("%s=========== %s (ID:%d,%d) ==========\n", loglevel, name, r->num,r->gen);
GString*gstr = font->getTag();
- msg("%s| Tag: %s\n", loglevel, name);
+ msg("%s| Tag: %s\n", loglevel, id);
if(font->isCIDFont()) msg("%s| is CID font\n", loglevel);
Ref embRef;
GBool embedded = font->getEmbeddedFontID(&embRef);
- if(font->getEmbeddedFontName())
- name = font->getEmbeddedFontName()->getCString();
+ char*embeddedName=0;
+ if(font->getEmbeddedFontName()) {
+ embeddedName = font->getEmbeddedFontName()->getCString();
+ }
if(embedded)
- msg("%s| Embedded name: %s id: %d\n",loglevel, FIXNULL(name), embRef.num);
+ msg("%s| Embedded id: %s id: %d\n",loglevel, FIXNULL(embeddedName), embRef.num);
gstr = font->getExtFontFile();
if(gstr)
if(font->isSymbolic()) msg("%s| is symbolic\n", loglevel);
if(font->isItalic()) msg("%s| is italic\n", loglevel);
if(font->isBold()) msg("%s| is bold\n", loglevel);
+
+ free(id);
+ free(name);
}
//void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) {printf("void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) \n");}
}
swfoutput_startclip(&output, line);
- clipping[clippos] ++;
+ states[statepos].clipping++;
gfxline_free(line);
}
void SWFOutputDev::eoClip(GfxState *state)
}
swfoutput_startclip(&output, line);
- clipping[clippos] ++;
+ states[statepos].clipping++;
gfxline_free(line);
}
return gTrue;
}
+char*renderModeDesc[]= {"fill", "stroke", "fill+stroke", "invisible",
+ "clip+fill", "stroke+clip", "fill+stroke+clip", "clip"};
+
+static char tmp_printstr[4096];
+char* makeStringPrintable(char*str)
+{
+ int len = strlen(str);
+ int dots = 0;
+ if(len>=80) {
+ len = 80;
+ dots = 1;
+ }
+ int t;
+ for(t=0;t<len;t++) {
+ char c = str[t];
+ if(c<32 || c>124) {
+ c = '.';
+ }
+ tmp_printstr[t] = c;
+ }
+ if(dots) {
+ tmp_printstr[len++] = '.';
+ tmp_printstr[len++] = '.';
+ tmp_printstr[len++] = '.';
+ }
+ tmp_printstr[len] = 0;
+ return tmp_printstr;
+}
+
void SWFOutputDev::beginString(GfxState *state, GString *s)
{
+ int render = state->getRender();
+ msg("<trace> beginString(%s) render=%d", s->getCString(), render);
double m11,m21,m12,m22;
// msg("<debug> %s beginstring \"%s\"\n", gfxstate2str(state), s->getCString());
state->getFontTransMat(&m11, &m12, &m21, &m22);
m11 *= state->getHorizScaling();
m21 *= state->getHorizScaling();
swfoutput_setfontmatrix(&output, m11, -m21, m12, -m22);
+ if(render != 3 && render != 0)
+ msg("<warning> Text rendering mode %d (%s) not fully supported yet (for text \"%s\")", render, renderModeDesc[render&7], makeStringPrintable(s->getCString()));
+ states[statepos].textRender = render;
}
+static int textCount = 0;
+
void SWFOutputDev::drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
CharCode c, Unicode *_u, int uLen)
{
+ textCount++;
+
+ int render = state->getRender();
// check for invisible text -- this is used by Acrobat Capture
- if ((state->getRender() & 3) == 3)
+ if (render == 3)
return;
+
+ if(states[statepos].textRender != render)
+ msg("<error> Internal error: drawChar.render!=beginString.render");
+
GfxRGB rgb;
double opaq = state->getFillOpacity();
state->getFillRGB(&rgb);
if(font->getType() == fontType3) {
/* type 3 chars are passed as graphics */
+ msg("<debug> type3 char at %f/%f", x, y);
return;
}
double x1,y1;
if(font->isCIDFont()) {
GfxCIDFont*cfont = (GfxCIDFont*)font;
- if(font->getType() == fontCIDType2) {
+ if(font->getType() == fontCIDType2)
CIDToGIDMap = cfont->getCIDToGID();
- }
} else {
Gfx8BitFont*font8;
font8 = (Gfx8BitFont*)font;
}
if (CIDToGIDMap) {
- msg("<debug> drawChar(%f, %f, c='%c' (%d), GID=%d, u=%d <%d>) CID=%d name=\"%s\"\n", x, y, (c&127)>=32?c:'?', c, CIDToGIDMap[c], u, uLen, font->isCIDFont(), FIXNULL(name));
+ msg("<debug> drawChar(%f, %f, c='%c' (%d), GID=%d, u=%d <%d>) CID=%d name=\"%s\" render=%d\n", x, y, (c&127)>=32?c:'?', c, CIDToGIDMap[c], u, uLen, font->isCIDFont(), FIXNULL(name), render);
swfoutput_drawchar(&output, x1, y1, name, CIDToGIDMap[c], u, &col);
} else {
- msg("<debug> drawChar(%f,%f,c='%c' (%d), u=%d <%d>) CID=%d name=\"%s\"\n",x,y,(c&127)>=32?c:'?',c,u, uLen, font->isCIDFont(), FIXNULL(name));
+ msg("<debug> drawChar(%f,%f,c='%c' (%d), u=%d <%d>) CID=%d name=\"%s\" render=%d\n",x,y,(c&127)>=32?c:'?',c,u, uLen, font->isCIDFont(), FIXNULL(name), render);
swfoutput_drawchar(&output, x1, y1, name, c, u, &col);
}
}
-void SWFOutputDev::endString(GfxState *state) {
+void SWFOutputDev::endString(GfxState *state)
+{
+ msg("<trace> endString()");
}
+void SWFOutputDev::endTextObject(GfxState *state)
+{
+ msg("<trace> endTextObject()");
+}
+
/* the logic seems to be as following:
first, beginType3Char is called, with the charcode and the coordinates.
if this function returns true, it already knew about the char and has now drawn it.
}
void SWFOutputDev::saveState(GfxState *state) {
- msg("<debug> saveState\n");
+ msg("<trace> saveState\n");
updateAll(state);
- if(clippos<64)
- clippos ++;
- else
+ if(statepos>=64) {
msg("<error> Too many nested states in pdf.");
- clipping[clippos] = 0;
+ return;
+ }
+ statepos ++;
+ states[statepos].clipping = 0; //? shouldn't this be the current value?
+ states[statepos].textRender = states[statepos-1].textRender;
};
void SWFOutputDev::restoreState(GfxState *state) {
- msg("<debug> restoreState\n");
+ msg("<trace> restoreState\n");
updateAll(state);
- while(clipping[clippos]) {
+ while(states[statepos].clipping) {
swfoutput_endclip(&output);
- clipping[clippos]--;
+ states[statepos].clipping--;
}
- clippos--;
+ statepos--;
}
char* SWFOutputDev::searchFont(char*name)
msg("<notice> Collection: %s", c.getCString());
}*/
- if (font->getType() == fontType1C ||
- font->getType() == fontCIDType0C) {
+ if (font->getType() == fontType1C) {
if (!(fontBuf = font->readEmbFontFile(xref, &fontLen))) {
fclose(f);
msg("<error> Couldn't read embedded font file");
if (!fcinitcalled) {
msg("<debug> Initializing FontConfig...");
fcinitcalled = true;
- if(FcInit()) {
+ if(!FcInit()) {
msg("<debug> FontConfig Initialization failed. Disabling.");
config_use_fontconfig = 0;
return 0;
// if we get an exact match
if (strcmp((char *)v, name) == 0) {
if (FcPatternGetString(match, "file", 0, &v) == FcResultMatch) {
- filename = strdup((char*)v);
+ filename = strdup((char*)v); // mem leak
char *nfn = strrchr(filename, '/');
if(nfn) fontname = strdup(nfn+1);
else fontname = filename;
match = FcFontMatch (0, pattern, &result);
if (FcPatternGetString(match, "file", 0, &v) == FcResultMatch) {
- filename = strdup((char*)v);
+ filename = strdup((char*)v); // mem leak
char *nfn = strrchr(filename, '/');
if(nfn) fontname = strdup(nfn+1);
else fontname = filename;
}
filename = searchFont(fontname);
if(!filename) {
- msg("<error> Couldn't find font %s- did you install the default fonts?");
+ msg("<error> Couldn't find font %s- did you install the default fonts?", fontname);
return 0;
}
exit(1);
}
if(oldname) {
- substitutesource[substitutepos] = oldname;
+ substitutesource[substitutepos] = strdup(oldname); //mem leak
substitutetarget[substitutepos] = fontname;
msg("<notice> substituting %s -> %s", FIXNULL(oldname), FIXNULL(fontname));
substitutepos ++;
}
- return strdup(filename);
+ return strdup(filename); //mem leak
}
void unlinkfont(char* filename)
too often */
for(t=0;t<substitutepos;t++) {
if(!strcmp(fontid, substitutesource[t])) {
- fontid = substitutetarget[t];
+ free(fontid);fontid=0;
+ fontid = strdup(substitutetarget[t]);
break;
}
}
swfoutput_setfont(&output, fontid, 0);
msg("<debug> updateFont(%s) [cached]", fontid);
+ free(fontid);
return;
}
type3Warning = gTrue;
showFontError(gfxFont, 2);
}
+ free(fontid);
return;
}
msg("<warning> Font %s %scould not be loaded.", fontname, embedded?"":"(not embedded) ");
msg("<warning> Try putting a TTF version of that font (named \"%s.ttf\") into /swftools/fonts", fontname);
fileName = substituteFont(gfxFont, fontid);
- if(fontid) { fontid = substitutetarget[substitutepos-1]; /*ugly hack*/};
+ if(fontid) { free(fontid);fontid = strdup(substitutetarget[substitutepos-1]); /*ugly hack*/};
msg("<notice> Font is now %s (%s)", fontid, fileName);
}
if(!fileName) {
msg("<error> Couldn't set font %s\n", fontid);
+ free(fontid);
return;
}
unlinkfont(fileName);
if(fileName)
free(fileName);
+ free(fontid);
}
#define SQR(x) ((x)*(x))
int width, int height, GBool invert,
GBool inlineImg)
{
+ if(states[statepos].textRender & 4) //clipped
+ return;
msg("<verbose> drawImageMask %dx%d, invert=%d inline=%d", width, height, invert, inlineImg);
drawGeneralImage(state,ref,str,width,height,0,invert,inlineImg,1, 0);
}
int width, int height, GfxImageColorMap *colorMap,
int *maskColors, GBool inlineImg)
{
+ if(states[statepos].textRender & 4) //clipped
+ return;
+
msg("<verbose> drawImage %dx%d, %s %s, inline=%d", width, height,
colorMap?"colorMap":"no colorMap",
maskColors?"maskColors":"no maskColors",