* fixed swf_CopySWF
[swftools.git] / pdf2swf / SWFOutputDev.cc
index 00499a9..37110fd 100644 (file)
@@ -77,6 +77,8 @@ typedef struct _fontfile
 static fontfile_t fonts[2048];
 static int fontnum = 0;
 
+static int config_use_fontconfig = 1;
+
 // swf <-> pdf pages
 // TODO: move into pdf_doc_t
 static int*pages = 0;
@@ -844,7 +846,7 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
     // check for invisible text -- this is used by Acrobat Capture
     if ((state->getRender() & 3) == 3)
        return;
-
+    Gushort *CIDToGIDMap = 0;
     GfxFont*font = state->getFont();
 
     if(font->getType() == fontType3) {
@@ -857,20 +859,29 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
     state->transform(x, y, &x1, &y1);
     
     Unicode u=0;
-    if(_u && uLen) 
+    char*name=0;
+
+    if(_u && uLen) {
        u = *_u;
+       if (u) {
+           int t;
+           /* find out char name from unicode index 
+              TODO: should be precomputed
+            */
+           for(t=0;t<sizeof(nameToUnicodeTab)/sizeof(nameToUnicodeTab[0]);t++) {
+               if(nameToUnicodeTab[t].u == u) {
+                   name = nameToUnicodeTab[t].name;
+                   break;
+               }
+           }
+       }
+    }
 
-    /* find out the character name */
-    char*name=0;
-    if(font->isCIDFont() && u) {
+    if(font->isCIDFont()) {
        GfxCIDFont*cfont = (GfxCIDFont*)font;
-       int t;
-       for(t=0;t<sizeof(nameToUnicodeTab)/sizeof(nameToUnicodeTab[0]);t++) {
-           /* todo: should be precomputed */
-           if(nameToUnicodeTab[t].u == u) {
-               name = nameToUnicodeTab[t].name;
-               break;
-           }
+
+       if(font->getType() == fontCIDType2) {
+           CIDToGIDMap = cfont->getCIDToGID();
        }
     } else {
        Gfx8BitFont*font8;
@@ -879,13 +890,14 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
        if(enc && enc[c])
           name = enc[c];
     }
-    
-    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);
+    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));
+       swfoutput_drawchar(&output, x1, y1, name, CIDToGIDMap[c], u);
+    } 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));
+       swfoutput_drawchar(&output, x1, y1, name, c, u);
+    }
 }
 
 void SWFOutputDev::endString(GfxState *state) { 
@@ -1308,6 +1320,9 @@ char* searchForSuitableFont(GfxFont*gfxFont)
     char*name = getFontName(gfxFont);
     char*fontname = 0;
     char*filename = 0;
+
+    if(!config_use_fontconfig)
+        return 0;
     
 #ifdef HAVE_FONTCONFIG
     FcPattern *pattern, *match;
@@ -1315,25 +1330,38 @@ char* searchForSuitableFont(GfxFont*gfxFont)
     FcChar8 *v;
 
     static int fcinitcalled = false; 
+        
+    msg("<debug> searchForSuitableFont(%s)", name);
     
     // call init ony once
     if (!fcinitcalled) {
+        msg("<debug> Initializing FontConfig...");
         fcinitcalled = true;
-       FcInit(); //leaks
+       if(FcInit()) {
+            msg("<debug> FontConfig Initialization failed. Disabling.");
+            config_use_fontconfig = 0;
+            return 0;
+        }
+        msg("<debug> ...initialized FontConfig");
     }
    
+    msg("<debug> FontConfig: Create \"%s\" Family Pattern", name);
     pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, name, NULL);
     if (gfxFont->isItalic()) // check for italic
+        msg("<debug> FontConfig: Adding Italic Slant");
        FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
     if (gfxFont->isBold()) // check for bold
+        msg("<debug> FontConfig: Adding Bold Weight");
         FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
 
+    msg("<debug> FontConfig: Try to match...");
     // 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) {
+        msg("<debug> FontConfig: family=%s", (char*)v);
         // if we get an exact match
         if (strcmp((char *)v, name) == 0) {
            if (FcPatternGetString(match, "file", 0, &v) == FcResultMatch) {
@@ -1342,6 +1370,7 @@ char* searchForSuitableFont(GfxFont*gfxFont)
                if(nfn) fontname = strdup(nfn+1);
                else    fontname = filename;
             }
+            msg("<debug> FontConfig: Returning \"%s\"", fontname);
         } else {
             // initialize patterns
             FcPatternDestroy(pattern);
@@ -1349,22 +1378,28 @@ char* searchForSuitableFont(GfxFont*gfxFont)
 
             // now match against serif etc.
            if (gfxFont->isSerif()) {
+                msg("<debug> FontConfig: Create Serif Family Pattern");
                 pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "serif", NULL);
             } else if (gfxFont->isFixedWidth()) {
+                msg("<debug> FontConfig: Create Monospace Family Pattern");
                 pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "monospace", NULL);
             } else {
+                msg("<debug> FontConfig: Create Sans Family Pattern");
                 pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "sans", NULL);
             }
 
             // check for italic
             if (gfxFont->isItalic()) {
+                msg("<debug> FontConfig: Adding Italic Slant");
                 int bb = FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
             }
             // check for bold
             if (gfxFont->isBold()) {
+                msg("<debug> FontConfig: Adding Bold Weight");
                 int bb = FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
             }
 
+            msg("<debug> FontConfig: Try to match... (2)");
             // configure and match using serif etc
            FcConfigSubstitute (0, pattern, FcMatchPattern);
             FcDefaultSubstitute (pattern);
@@ -1376,6 +1411,7 @@ char* searchForSuitableFont(GfxFont*gfxFont)
                if(nfn) fontname = strdup(nfn+1);
                else    fontname = filename;
            }
+            msg("<debug> FontConfig: Returning \"%s\"", fontname);
         }        
     }
 
@@ -1916,6 +1952,10 @@ void pdfswf_setparameter(char*name, char*value)
        zoom = atoi(value);
     } else if(!strcmp(name, "fontdir")) {
         pdfswf_addfontdir(value);
+    } else if(!strcmp(name, "languagedir")) {
+        pdfswf_addlanguagedir(value);
+    } else if(!strcmp(name, "fontconfig")) {
+        config_use_fontconfig = atoi(value);
     } else {
        swfoutput_setparameter(name, value);
     }
@@ -1932,6 +1972,38 @@ void pdfswf_addfont(char*filename)
     }
 }
 
+static char* dirseparator()
+{
+#ifdef WIN32
+    return "\\";
+#else
+    return "/";
+#endif
+}
+
+void pdfswf_addlanguagedir(char*dir)
+{
+    if(!globalParams)
+        globalParams = new GlobalParams("");
+    
+    msg("<notice> Adding %s to language pack directories", dir);
+
+    int l;
+    FILE*fi = 0;
+    char* config_file = (char*)malloc(strlen(dir) + 1 + sizeof("add-to-xpdfrc"));
+    strcpy(config_file, dir);
+    strcat(config_file, dirseparator());
+    strcat(config_file, "add-to-xpdfrc");
+
+    fi = fopen(config_file, "rb");
+    if(!fi) {
+        msg("<error> Could not open %s", config_file);
+        return;
+    }
+    globalParams->parseFile(new GString(config_file), fi);
+    fclose(fi);
+}
+
 void pdfswf_addfontdir(char*dirname)
 {
 #ifdef HAVE_DIRENT_H
@@ -1963,11 +2035,7 @@ void pdfswf_addfontdir(char*dirname)
        {
            char*fontname = (char*)malloc(strlen(dirname)+strlen(name)+2);
            strcpy(fontname, dirname);
-#ifdef WIN32
-               strcat(fontname, "\\");
-#else
-               strcat(fontname, "/");
-#endif
+            strcat(fontname, dirseparator());
            strcat(fontname, name);
            msg("<verbose> Adding %s to fonts", fontname);
            pdfswf_addfont(fontname);
@@ -1975,7 +2043,7 @@ void pdfswf_addfontdir(char*dirname)
     }
     closedir(dir);
 #else
-    msg("<warning> No dirent.h- unable to add font dir %s");
+    msg("<warning> No dirent.h- unable to add font dir %s", dir);
 #endif
 }
 
@@ -2006,7 +2074,8 @@ pdf_doc_t* pdf_init(char*filename, char*userPassword)
     Object info;
 
     // read config file
-    globalParams = new GlobalParams("");
+    if(!globalParams)
+        globalParams = new GlobalParams("");
 
     // open PDF file
     if (userPassword && userPassword[0]) {
@@ -2083,7 +2152,7 @@ class MemCheck
 {
     public: ~MemCheck()
     {
-        delete globalParams;
+        delete globalParams;globalParams=0;
         Object::memCheck(stderr);
         gMemReport(stderr);
     }