#include <string.h>
#include <unistd.h>
#include "../config.h"
+#ifdef HAVE_FONTCONFIG_H
+#include <fontconfig.h>
+#endif
//xpdf header files
#include "config.h"
#include "gfile.h"
#include "GlobalParams.h"
//swftools header files
#include "swfoutput.h"
+#include "SWFOutputDev.h"
#include "../lib/log.h"
#include <math.h>
static int numpages;
static int currentpage;
-static char*fonts[2048];
+typedef struct _fontfile
+{
+ char*filename;
+ int used;
+} fontfile_t;
+
+static fontfile_t fonts[2048];
static int fontnum = 0;
// swf <-> pdf pages
{
char* name = getFontID(font);
Ref* r=font->getID();
- msg("%s=========== %s (ID:%d,%d) ==========\n", loglevel, name, r->num,r->gen);
+ msg("%s=========== %s (ID:%d,%d) ==========\n", loglevel, getFontName(font), r->num,r->gen);
GString*gstr = font->getTag();
m11 *= state->getHorizScaling();
m21 *= state->getHorizScaling();
swfoutput_setfontmatrix(&output, m11, -m21, m12, -m22);
+
+ msg("<debug> fontmatrix %7.3f %7.3f\n", m11,-m21);
+ msg("<debug> fontmatrix %7.3f %7.3f\n", m12,-m22);
}
void SWFOutputDev::drawChar(GfxState *state, double x, double y,
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));
+ x1 = (int)(x1+0.5);
+ y1 = (int)(y1+0.5);
+
int ret = swfoutput_drawchar(&output, x1, y1, name, c, u);
}
{
int i;
char*filename=0;
+ int is_standard_font = 0;
- msg("<verbose> SearchT1Font(%s)", name);
+ msg("<verbose> SearchFont(%s)", name);
/* see if it is a pdf standard font */
for(i=0;i<sizeof(pdf2t1map)/sizeof(mapping);i++)
if(!strcmp(name, pdf2t1map[i].pdffont))
{
name = pdf2t1map[i].filename;
+ is_standard_font = 1;
break;
}
}
/* look in all font files */
for(i=0;i<fontnum;i++)
{
- if(strstr(fonts[i], name))
+ if(strstr(fonts[i].filename, name))
{
- return fonts[i];
+ if(!fonts[i].used) {
+
+ fonts[i].used = 1;
+ if(!is_standard_font)
+ msg("<notice> Using %s for %s", fonts[i].filename, name);
+ }
+ return fonts[i].filename;
}
}
return 0;
char* substitutesource[256];
int substitutepos = 0;
+char* searchForSuitableFont(GfxFont*gfxFont)
+{
+ char*name = getFontName(gfxFont);
+ char*fontname = 0;
+ char*filename = 0;
+
+#ifdef HAVE_FONTCONFIG
+ FcPattern *pattern, *match;
+ FcResult result;
+ FcChar8 *v;
+
+ // call init ony once
+ static int fcinitcalled = false;
+ if (!fcinitcalled) {
+ fcinitcalled = true;
+ FcInit();
+ }
+
+ pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, name, NULL);
+ if (gfxFont->isItalic()) // check for italic
+ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
+ if (gfxFont->isBold()) // check for bold
+ FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
+
+ // configure and match using the original font name
+ FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcDefaultSubstitute(pattern);
+ match = FcFontMatch(0, pattern, &result);
+
+ if (FcPatternGetString(match, "family", 0, &v) == FcResultMatch) {
+ // if we get an exact match
+ if (strcmp((char *)v, name) == 0) {
+ if (FcPatternGetString(match, "file", 0, &v) == FcResultMatch) {
+ filename = strdup((char*)v);
+ char *nfn = strrchr(filename, '/');
+ if(nfn) fontname = strdup(nfn+1);
+ else fontname = filename;
+ }
+ } else {
+ // initialize patterns
+ FcPatternDestroy(pattern);
+ FcPatternDestroy(match);
+
+ // now match against serif etc.
+ if (gfxFont->isSerif()) {
+ pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "serif", NULL);
+ } else if (gfxFont->isFixedWidth()) {
+ pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "monospace", NULL);
+ } else {
+ pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "sans", NULL);
+ }
+
+ // check for italic
+ if (gfxFont->isItalic()) {
+ int bb = FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
+ }
+ // check for bold
+ if (gfxFont->isBold()) {
+ int bb = FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
+ }
+
+ // configure and match using serif etc
+ FcConfigSubstitute (0, pattern, FcMatchPattern);
+ FcDefaultSubstitute (pattern);
+ match = FcFontMatch (0, pattern, &result);
+
+ if (FcPatternGetString(match, "file", 0, &v) == FcResultMatch) {
+ filename = strdup((char*)v);
+ char *nfn = strrchr(filename, '/');
+ if(nfn) fontname = strdup(nfn+1);
+ else fontname = filename;
+ }
+ }
+ }
+
+ //printf("FONTCONFIG: pattern");
+ //FcPatternPrint(pattern);
+ //printf("FONTCONFIG: match");
+ //FcPatternPrint(match);
+
+ FcPatternDestroy(pattern);
+ FcPatternDestroy(match);
+
+ pdfswf_addfont(filename);
+ return fontname;
+#else
+ return 0;
+#endif
+}
+
char* SWFOutputDev::substituteFont(GfxFont*gfxFont, char* oldname)
{
- char*fontname = "Times-Roman";
- msg("<verbose> substituteFont(,%s)", FIXNULL(oldname));
- char*filename = searchFont(fontname);
+ char*fontname = 0, *filename = 0;
+ msg("<notice> subsituteFont(%s)", oldname);
+
+ if(!(fontname = searchForSuitableFont(gfxFont))) {
+ fontname = "Times-Roman";
+ }
+ filename = searchFont(fontname);
+
if(substitutepos>=sizeof(substitutesource)/sizeof(char*)) {
msg("<fatal> Too many fonts in file.");
exit(1);
}
// look for Type 3 font
- if (!type3Warning && gfxFont->getType() == fontType3) {
- type3Warning = gTrue;
- showFontError(gfxFont, 2);
+ if (gfxFont->getType() == fontType3) {
+ if(!type3Warning) {
+ type3Warning = gTrue;
+ showFontError(gfxFont, 2);
+ }
+ return;
}
/* now either load the font, or find a substitution */
}
if(!fileName) {
char * fontname = getFontName(gfxFont);
- msg("<warning> Font %s could not be loaded.", fontname);
+ 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*/};
+ msg("<notice> Font is now %s (%s)", fontid, fileName);
}
if(!fileName) {
void pdfswf_setparameter(char*name, char*value)
{
- if(!strcmp(name, "drawonlyshapes")) {
- drawonlyshapes = atoi(value);
- } else if(!strcmp(name, "ignoredraworder")) {
- ignoredraworder = atoi(value);
- } else if(!strcmp(name, "linksopennewwindow")) {
- opennewwindow = atoi(value);
- } else if(!strcmp(name, "storeallcharacters")) {
- storeallcharacters = atoi(value);
- } else if(!strcmp(name, "enablezlib")) {
- enablezlib = atoi(value);
- } else if(!strcmp(name, "insertstop")) {
- insertstoptag = atoi(value);
- } else if(!strcmp(name, "flashversion")) {
- flashversion = atoi(value);
- } else if(!strcmp(name, "jpegquality")) {
- int val = atoi(value);
- if(val<0) val=0;
- if(val>100) val=100;
- jpegquality = val;
- } else if(!strcmp(name, "outputfilename")) {
+ if(!strcmp(name, "outputfilename")) {
swffilename = value;
} else if(!strcmp(name, "caplinewidth")) {
caplinewidth = atof(value);
- } else if(!strcmp(name, "splinequality")) {
- int v = atoi(value);
- v = 500-(v*5); // 100% = 0.25 pixel, 0% = 25 pixel
- if(v<1) v = 1;
- splinemaxerror = v;
- } else if(!strcmp(name, "fontquality")) {
- int v = atoi(value);
- v = 500-(v*5); // 100% = 0.25 pixel, 0% = 25 pixel
- if(v<1) v = 1;
- fontsplinemaxerror = v;
} else {
- fprintf(stderr, "unknown parameter: %s (=%s)\n", name, value);
+ swfoutput_setparameter(name, value);
}
}
void pdfswf_addfont(char*filename)
{
- fonts[fontnum++] = filename;
+ fontfile_t f;
+ memset(&f, 0, sizeof(fontfile_t));
+ f.filename = filename;
+ fonts[fontnum++] = f;
}
-void pdfswf_drawonlyshapes()
-{
- drawonlyshapes = 1;
-}
-
-void pdfswf_ignoredraworder()
-{
- ignoredraworder = 1;
-}
-
-void pdfswf_linksopennewwindow()
-{
- opennewwindow = 1;
-}
-
-void pdfswf_storeallcharacters()
-{
- storeallcharacters = 1;
-}
-
-void pdfswf_enablezlib()
-{
- enablezlib = 1;
-}
-
-void pdfswf_jpegquality(int val)
-{
- if(val<0) val=0;
- if(val>100) val=100;
- jpegquality = val;
-}
-
-void pdfswf_setoutputfilename(char*_filename)
-{
- swffilename = _filename;
+/* TODO: get rid of this */
+void pdfswf_drawonlyshapes() { pdfswf_setparameter("drawonlyshapes", "1"); }
+void pdfswf_ignoredraworder() { pdfswf_setparameter("ignoredraworder", "1"); }
+void pdfswf_linksopennewwindow() { pdfswf_setparameter("opennewwindow", "1"); }
+void pdfswf_storeallcharacters() { pdfswf_setparameter("storeallcharacters", "1"); }
+void pdfswf_enablezlib() { pdfswf_setparameter("enablezlib", "1"); }
+void pdfswf_setoutputfilename(char*_filename) { swffilename = _filename; }
+void pdfswf_insertstop() { pdfswf_setparameter("insertstoptag", "1"); }
+void pdfswf_jpegquality(int val) {
+ char tmp[32];
+ sprintf(tmp, "%d", val);
+ pdfswf_setparameter("jpegquality", tmp);
}
-
-void pdfswf_insertstop()
-{
- insertstoptag = 1;
+void pdfswf_setversion(int n) {
+ char tmp[32];
+ sprintf(tmp, "%d", n);
+ pdfswf_setparameter("flashversion", tmp);
}
-void pdfswf_setversion(int n)
-{
- flashversion = n;
-}
void pdfswf_convertpage(int page)
doc->displayPage((OutputDev*)output, currentpage, /*dpi*/72, /*rotate*/0, /*doLinks*/(int)1);
}
}
-
int pdfswf_numpages()
{
return doc->getNumPages();