diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc
index 77a053d..904b7fb 100644
--- a/poppler/GlobalParams.cc
+++ b/poppler/GlobalParams.cc
@@ -552,6 +552,7 @@ GlobalParams::GlobalParams(const char *customPopplerDataDir)
 #ifdef _WIN32
   // baseDir will be set by a call to setBaseDir
   baseDir = new GooString();
+  substFiles = new GooHash(gTrue);
 #else
   baseDir = appendToPath(getHomeDir(), ".xpdf");
 #endif
@@ -788,6 +789,9 @@ GlobalParams::~GlobalParams() {
   deleteGooHash(fontFiles, GooString);
   deleteGooList(fontDirs, GooString);
   deleteGooHash(ccFontFiles, GooString);
+#ifdef _WIN32
+  deleteGooHash(substFiles, GooString);
+#endif
   delete sysFonts;
   if (psFile) {
     delete psFile;
diff --git a/poppler/GlobalParams.h b/poppler/GlobalParams.h
index d72793d..68cfd16 100644
--- a/poppler/GlobalParams.h
+++ b/poppler/GlobalParams.h
@@ -289,6 +289,7 @@ private:
   GooList *toUnicodeDirs;		// list of ToUnicode CMap dirs [GooString]
 #ifdef _WIN32
   GBool baseFontsInitialized;
+  GooHash *substFiles;	// windows font substitutes (for CID fonts)
 #endif
   GooHash *fontFiles;		// font files: font name mapped to path
 				//   [GString]
diff --git a/poppler/GlobalParamsWin.cc b/poppler/GlobalParamsWin.cc
index c62e2cd..c106db3 100644
--- a/poppler/GlobalParamsWin.cc
+++ b/poppler/GlobalParamsWin.cc
@@ -40,6 +40,11 @@ description for all fonts available in Windows. That's how MuPDF works.
 #include "FontEncodingTables.h"
 #include "GlobalParams.h"
 #include "GfxFont.h"
+#include <sys/stat.h>
+#include "Object.h"
+#include "Stream.h"
+#include "Lexer.h"
+#include "Parser.h"
 
 #if MULTITHREADED
 #  define lockGlobalParams            gLockMutex(&mutex)
@@ -58,6 +63,7 @@ description for all fonts available in Windows. That's how MuPDF works.
 #endif
 
 #define DEFAULT_SUBSTITUTE_FONT "Helvetica"
+#define DEFAULT_CID_FONT "MS-Mincho"
 
 static struct {
     const char *name;
@@ -147,6 +153,8 @@ static struct {
     {"Georgia-Bold", NULL, "georgiab.ttf"},
     {"Georgia-Italic", NULL, "georgiai.ttf"},
     {"Georgia-BoldItalic", NULL, "georgiaz.ttf"},
+    // default CID font:
+    {"MS-Mincho", NULL, "msmincho.ttf"},
 
     {NULL}
 };
@@ -346,6 +354,12 @@ SysFontInfo *SysFontList::makeWindowsFont(char *name, int fontNum,
 
 void GlobalParams::setupBaseFonts(char * dir)
 {
+	  const char *dataRoot = popplerDataDir ? popplerDataDir : POPPLER_DATADIR;
+	  GooString *fileName = NULL;
+	  struct stat buf;
+	  FILE *file;
+	  int size = 0;
+	  
     if (baseFontsInitialized)
         return;
     baseFontsInitialized = true;
@@ -381,20 +395,81 @@ void GlobalParams::setupBaseFonts(char * dir)
     if (winFontDir[0]) {
       sysFonts->scanWindowsFonts(new GooString(winFontDir));
     }
+
+	  fileName = new GooString(dataRoot);
+	  fileName->append("/cidfmap");
+	  if (stat(fileName->getCString(), &buf) == 0) {
+		  size = buf.st_size;
+	  }
+	  // try to open file
+	  file = fopen(fileName->getCString(), "rb");
+
+	  if (file != NULL) {
+		  Parser *parser;
+		  Object obj1, obj2;
+
+		  obj1.initNull();
+		  parser = new Parser(NULL,
+			  new Lexer(NULL,
+			  new FileStream(file, 0, gFalse, size, &obj1)),
+			  gTrue);
+		  obj1.free();
+		  parser->getObj(&obj1);
+		  while (!obj1.isEOF()) {
+			  parser->getObj(&obj2);
+			  if (obj1.isName()) {
+				  // Substitutions
+				  if (obj2.isDict()) {
+					  Object obj3;
+					  obj2.getDict()->lookup("Path", &obj3);
+					  if (obj3.isString())
+						  addFontFile(new GooString(obj1.getName()), obj3.getString()->copy());
+					  obj3.free();
+				  // Aliases
+				  } else if (obj2.isName()) {
+					  substFiles->add(new GooString(obj1.getName()), new GooString(obj2.getName()));
+				  }
+			  }
+			  obj2.free();
+			  obj1.free();
+			  parser->getObj(&obj1);
+			  // skip trailing ';'
+			  while (obj1.isCmd(";")) {
+				  obj1.free();
+				  parser->getObj(&obj1);
+			  }
+		  }
+		  fclose(file);
+		  delete parser;
+	  }
 }
 
-static char *findSubstituteName(const char *origName)
+static char *findSubstituteName(GfxFont *font, GooHash *substFiles, const char *origName)
 {
     assert(origName);
     if (!origName) return NULL;
+	  GooString *name2 = new GooString(origName);
+	  int n = strlen(origName);
+	  // remove trailing "-Identity-H"
+	  if (n > 11 && !strcmp(name2->getCString() + n - 11, "-Identity-H")) {
+		  name2->del(n - 11, 11);
+		  n -= 11;
+	  }
+	  GooString *substName = (GooString *)substFiles->lookup(name2);
+	  if (substName != NULL) {
+		  delete name2;
+		  return substName->getCString();
+	  }
+
     /* TODO: try to at least guess bold/italic/bolditalic from the name */
-    return DEFAULT_SUBSTITUTE_FONT;
+	  delete name2;
+	  return (font->isCIDFont()) ? DEFAULT_CID_FONT: DEFAULT_SUBSTITUTE_FONT;
 }
 
 /* Windows implementation of external font matching code */
 GooString *GlobalParams::findSystemFontFile(GfxFont *font,
 					  SysFontType *type,
-					  int *fontNum, GooString * /*substituteFontName*/) {
+					  int *fontNum, GooString *substituteFontName) {
   SysFontInfo *fi;
   GooString *path = NULL;
   GooString *fontName = font->getName();
@@ -406,14 +481,21 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
     *type = fi->type;
     *fontNum = fi->fontNum;
   } else {
-    GooString *substFontName = new GooString(findSubstituteName(fontName->getCString()));
+    GooString *substFontName = new GooString(findSubstituteName(font, substFiles, fontName->getCString()));
+	  GooString *path2 = NULL;
     error(errSyntaxError, -1, "Couldn't find a font for '{0:t}', subst is '{1:t}'", fontName, substFontName);
-    if ((fi = sysFonts->find(substFontName, gFalse))) {
-      path = fi->path->copy();
-      *type = fi->type;
-      *fontNum = fi->fontNum;
-    }
-  }      
+	  if ((path2 = (GooString *)fontFiles->lookup(substFontName))) {
+	    path = new GooString(path2);
+	    if (substituteFontName)
+		    substituteFontName->Set(path->getCString());
+	    if (!strcasecmp(path->getCString() + path->getLength() - 4, ".ttc")) {
+		    *type = sysFontTTC;
+	    } else {
+		    *type = sysFontTTF;
+	    }
+	    *fontNum = 0;
+	  }
+  }
   unlockGlobalParams;
   return path;
 }
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index d8e3ac3..19d705c 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -1815,6 +1815,7 @@ void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
     setupType3Font(font, psName, parentResDict);
   } else {
     fontLoc = font->locateFont(xref, gTrue);
+  if (fontLoc != NULL) {
     switch (fontLoc->locType) {
     case gfxFontLocEmbedded:
       switch (fontLoc->fontType) {
@@ -1886,6 +1887,7 @@ void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
       psName = fontLoc->path->copy();
       break;
     }
+  }
 
     if (!psName) {
       if (font->isCIDFont()) {
@@ -2363,9 +2365,6 @@ void PSOutputDev::setupExternalCIDTrueTypeFont(GfxFont *font,
   FoFiTrueType *ffTT;
   int *codeToGID;
   int codeToGIDLen;
-  CharCodeToUnicode *ctu;
-  Unicode *uBuf;
-  int cmap, code;
 
   // beginning comment
   writePSFmt("%%BeginResource: font {0:t}\n", psName);
@@ -2381,57 +2380,40 @@ void PSOutputDev::setupExternalCIDTrueTypeFont(GfxFont *font,
     if (ffTT->getEmbeddingRights() >= 1) {
 
       // create a CID-to-GID mapping, via Unicode
-      if ((ctu = ((GfxCIDFont *)font)->getToUnicode())) {
-	// look for a Unicode cmap
-	for (cmap = 0; cmap < ffTT->getNumCmaps(); ++cmap) {
-	  if ((ffTT->getCmapPlatform(cmap) == 3 &&
-	       ffTT->getCmapEncoding(cmap) == 1) ||
-	      ffTT->getCmapPlatform(cmap) == 0) {
-	    break;
-	  }
-	}
-	if (cmap < ffTT->getNumCmaps()) {
-	  // map CID -> Unicode -> GID
-	  codeToGIDLen = ctu->getLength();
-	  codeToGID = (int *)gmallocn(codeToGIDLen, sizeof(int));
-	  for (code = 0; code < codeToGIDLen; ++code) {
-	    int n = ctu->mapToUnicode(code, &uBuf);
-	    if (n > 0) {
-	      codeToGID[code] = ffTT->mapCodeToGID(cmap, uBuf[0]);
+		  codeToGID = NULL;
+		  codeToGIDLen = 0;
+		  if (((GfxCIDFont *)font)->getCIDToGID()) {
+			  codeToGIDLen = ((GfxCIDFont *)font)->getCIDToGIDLen();
+			  if (codeToGIDLen) {
+				  codeToGID = (int *)gmallocn(codeToGIDLen, sizeof(int));
+				  memcpy(codeToGID, ((GfxCIDFont *)font)->getCIDToGID(),
+					  codeToGIDLen * sizeof(int));
+			  }
+		  } else {
+			  codeToGID = ((GfxCIDFont *)font)->getCodeToGIDMap(ffTT, &codeToGIDLen);
+		  }
+      if (ffTT->isOpenTypeCFF()) {
+	      ffTT->convertToCIDType0(psName->getCString(),
+				  codeToGID, codeToGIDLen,
+				  outputFunc, outputStream);
+      } else if (globalParams->getPSLevel() >= psLevel3) {
+	      // Level 3: use a CID font
+	      ffTT->convertToCIDType2(psName->getCString(),
+				  codeToGID, codeToGIDLen,
+				  needVerticalMetrics,
+				  outputFunc, outputStream);
 	    } else {
-	      codeToGID[code] = 0;
+	      // otherwise: use a non-CID composite font
+	      ffTT->convertToType0(psName->getCString(),
+				  codeToGID, codeToGIDLen,
+				  needVerticalMetrics,
+				  outputFunc, outputStream);
 	    }
-	  }
-          if (ffTT->isOpenTypeCFF()) {
-	    ffTT->convertToCIDType0(psName->getCString(),
-				 codeToGID, codeToGIDLen,
-				 outputFunc, outputStream);
-          } else if (globalParams->getPSLevel() >= psLevel3) {
-	    // Level 3: use a CID font
-	    ffTT->convertToCIDType2(psName->getCString(),
-				    codeToGID, codeToGIDLen,
-				    needVerticalMetrics,
-				    outputFunc, outputStream);
-	  } else {
-	    // otherwise: use a non-CID composite font
-	    ffTT->convertToType0(psName->getCString(),
-				 codeToGID, codeToGIDLen,
-				 needVerticalMetrics,
-				 outputFunc, outputStream);
-	  }
-	  gfree(codeToGID);
-	}
-	ctu->decRefCnt();
-      } else {
-	error(errSyntaxError, -1,
-	      "Couldn't find a mapping to Unicode for font '{0:s}'",
-	      font->getName() ? font->getName()->getCString() : "(unnamed)");
-      }
+	    gfree(codeToGID);
     } else {
       error(errSyntaxError, -1,
 	    "TrueType font '%s' does not allow embedding",
 	    font->getName() ? font->getName()->getCString() : "(unnamed)");
-	    
     }
     delete ffTT;
   }
