//========================================================================
//
// GlobalParams.cc
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2005 Martin Kretzschmar <martink@gnome.org>
// Copyright (C) 2005, 2006 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2005, 2007-2010, 2012, 2015, 2017-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
// Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2006 Takashi Iwai <tiwai@suse.de>
// Copyright (C) 2006 Ed Catmur <ed@catmur.co.uk>
// Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
// Copyright (C) 2007, 2009 Jonathan Kew <jonathan_kew@sil.org>
// Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com>
// Copyright (C) 2009, 2011, 2012, 2015 William Bader <williambader@hotmail.com>
// Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
// Copyright (C) 2010, 2012 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2010 Patrick Spendrin <ps_ml@gmx.de>
// Copyright (C) 2010 Jakub Wilk <jwilk@jwilk.net>
// Copyright (C) 2011 Pino Toscano <pino@kde.org>
// Copyright (C) 2011 Koji Otani <sho@bbr.jp>
// Copyright (C) 2012 Yi Yang <ahyangyi@gmail.com>
// Copyright (C) 2012, 2017 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2012 Peter Breitenlohner <peb@mppmu.mpg.de>
// Copyright (C) 2013, 2014 Jason Crain <jason@aquaticape.us>
// Copyright (C) 2017 Christoph Cullmann <cullmann@kde.org>
// Copyright (C) 2017 Jean Ghali <jghali@libertysurf.fr>
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
// Copyright (C) 2019 Christian Persch <chpe@src.gnome.org>
// Copyright (C) 2019 Oliver Sander <oliver.sander@tu-dresden.de>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#include <config.h>

#include <string.h>
#include <stdio.h>
#include <ctype.h>
#ifdef _WIN32
#  include <shlobj.h>
#  include <mbstring.h>
#endif
#include "goo/glibc.h"
#include "goo/gmem.h"
#include "goo/GooString.h"
#include "goo/gfile.h"
#include "goo/gdir.h"
#include "Error.h"
#include "NameToCharCode.h"
#include "CharCodeToUnicode.h"
#include "UnicodeMap.h"
#include "CMap.h"
#include "BuiltinFontTables.h"
#include "FontEncodingTables.h"
#include "GlobalParams.h"
#include "GfxFont.h"

#ifdef WITH_FONTCONFIGURATION_FONTCONFIG
#include <fontconfig/fontconfig.h>
#endif

#ifdef _MSC_VER
#  define strcasecmp stricmp
#else
#  include <strings.h>
#endif

#ifndef FC_WEIGHT_BOOK
#define FC_WEIGHT_BOOK 75
#endif

#include "NameToUnicodeTable.h"
#include "UnicodeMapTables.h"
#include "UnicodeMapFuncs.h"

//------------------------------------------------------------------------

#define cidToUnicodeCacheSize     4
#define unicodeToUnicodeCacheSize 4

//------------------------------------------------------------------------

GlobalParams *globalParams = nullptr;

#if defined(ENABLE_RELOCATABLE) && defined(_WIN32)

/* search for data relative to where we are installed */

static HMODULE hmodule;

extern "C" {
  /* Provide declaration to squelch -Wmissing-declarations warning */
  BOOL WINAPI
  DllMain (HINSTANCE hinstDLL,
	   DWORD     fdwReason,
	   LPVOID    lpvReserved);

  BOOL WINAPI
  DllMain (HINSTANCE hinstDLL,
	   DWORD     fdwReason,
	   LPVOID    lpvReserved)
  {
    switch (fdwReason) {
      case DLL_PROCESS_ATTACH:
	hmodule = hinstDLL;
	break;
    }

    return TRUE;
  }
}

static const char *
get_poppler_datadir (void)
{
  static char retval[MAX_PATH];
  static int beenhere = 0;

  unsigned char *p;

  if (beenhere)
    return retval;

  if (!GetModuleFileNameA (hmodule, (CHAR *) retval, sizeof(retval) - 20))
    return POPPLER_DATADIR;

  p = _mbsrchr ((unsigned char *) retval, '\\');
  *p = '\0';
  p = _mbsrchr ((unsigned char *) retval, '\\');
  if (p) {
    if (stricmp ((const char *) (p+1), "bin") == 0)
      *p = '\0';
  }
  strcat (retval, "\\share\\poppler");

  beenhere = 1;

  return retval;
}

#undef POPPLER_DATADIR
#define POPPLER_DATADIR get_poppler_datadir ()

#endif

//------------------------------------------------------------------------
// SysFontInfo
//------------------------------------------------------------------------

class SysFontInfo {
public:

  GooString *name;
  bool bold;
  bool italic;
  bool oblique;
  bool fixedWidth;
  GooString *path;
  SysFontType type;
  int fontNum;			// for TrueType collections
  GooString *substituteName;

  SysFontInfo(GooString *nameA, bool boldA, bool italicA, bool obliqueA, bool fixedWidthA,
	      GooString *pathA, SysFontType typeA, int fontNumA, GooString *substituteNameA);
  ~SysFontInfo();
  SysFontInfo(const SysFontInfo &) = delete;
  SysFontInfo& operator=(const SysFontInfo&) = delete;
  bool match(SysFontInfo *fi);
  bool match(GooString *nameA, bool boldA, bool italicA, bool obliqueA, bool fixedWidthA);
  bool match(GooString *nameA, bool boldA, bool italicA);
};

SysFontInfo::SysFontInfo(GooString *nameA, bool boldA, bool italicA, bool obliqueA, bool fixedWidthA,
			 GooString *pathA, SysFontType typeA, int fontNumA, GooString *substituteNameA) {
  name = nameA;
  bold = boldA;
  italic = italicA;
  oblique = obliqueA;
  fixedWidth = fixedWidthA;
  path = pathA;
  type = typeA;
  fontNum = fontNumA;
  substituteName = substituteNameA;
}

SysFontInfo::~SysFontInfo() {
  delete name;
  delete path;
  delete substituteName;
}

bool SysFontInfo::match(SysFontInfo *fi) {
  return !strcasecmp(name->c_str(), fi->name->c_str()) &&
         bold == fi->bold && italic == fi->italic && oblique == fi->oblique && fixedWidth == fi->fixedWidth;
}

bool SysFontInfo::match(GooString *nameA, bool boldA, bool italicA, bool obliqueA, bool fixedWidthA) {
  return !strcasecmp(name->c_str(), nameA->c_str()) &&
         bold == boldA && italic == italicA && oblique == obliqueA && fixedWidth == fixedWidthA;
}

bool SysFontInfo::match(GooString *nameA, bool boldA, bool italicA) {
  return !strcasecmp(name->c_str(), nameA->c_str()) &&
         bold == boldA && italic == italicA;
}

//------------------------------------------------------------------------
// SysFontList
//------------------------------------------------------------------------

class SysFontList {
public:

  SysFontList();
  ~SysFontList();
  SysFontList(const SysFontList &) = delete;
  SysFontList& operator=(const SysFontList &) = delete;
  SysFontInfo *find(const GooString *name, bool isFixedWidth, bool exact);

#ifdef _WIN32
  void scanWindowsFonts(GooString *winFontDir);
#endif
#ifdef WITH_FONTCONFIGURATION_FONTCONFIG
  void addFcFont(SysFontInfo *si) {fonts->push_back(si);}
#endif
private:

#ifdef _WIN32
  SysFontInfo *makeWindowsFont(const char *name, int fontNum,
			       const char *path);
#endif

  std::vector<SysFontInfo*> *fonts;
};

SysFontList::SysFontList() {
  fonts = new std::vector<SysFontInfo*>();
}

SysFontList::~SysFontList() {
  for (auto entry : *fonts) {
    delete entry;
  }
  delete fonts;
}

SysFontInfo *SysFontList::find(const GooString *name, bool fixedWidth, bool exact) {
  GooString *name2;
  bool bold, italic, oblique;
  SysFontInfo *fi;
  int n;

  name2 = name->copy();

  // remove space, comma, dash chars
  {
    int i = 0;
    while (i < name2->getLength()) {
        const char c = name2->getChar(i);
        if (c == ' ' || c == ',' || c == '-') {
        name2->del(i);
        } else {
        ++i;
        }
    }
    n = name2->getLength();
  }

  // remove trailing "MT" (Foo-MT, Foo-BoldMT, etc.)
  if (n > 2 && !strcmp(name2->c_str() + n - 2, "MT")) {
    name2->del(n - 2, 2);
    n -= 2;
  }

  // look for "Regular"
  if (n > 7 && !strcmp(name2->c_str() + n - 7, "Regular")) {
    name2->del(n - 7, 7);
    n -= 7;
  }

  // look for "Italic"
  if (n > 6 && !strcmp(name2->c_str() + n - 6, "Italic")) {
    name2->del(n - 6, 6);
    italic = true;
    n -= 6;
  } else {
    italic = false;
  }

  // look for "Oblique"
  if (n > 6 && !strcmp(name2->c_str() + n - 7, "Oblique")) {
    name2->del(n - 7, 7);
    oblique = true;
    n -= 6;
  } else {
    oblique = false;
  }

  // look for "Bold"
  if (n > 4 && !strcmp(name2->c_str() + n - 4, "Bold")) {
    name2->del(n - 4, 4);
    bold = true;
    n -= 4;
  } else {
    bold = false;
  }

  // remove trailing "MT" (FooMT-Bold, etc.)
  if (n > 2 && !strcmp(name2->c_str() + n - 2, "MT")) {
    name2->del(n - 2, 2);
    n -= 2;
  }

  // remove trailing "PS"
  if (n > 2 && !strcmp(name2->c_str() + n - 2, "PS")) {
    name2->del(n - 2, 2);
    n -= 2;
  }

  // remove trailing "IdentityH"
  if (n > 9 && !strcmp(name2->c_str() + n - 9, "IdentityH")) {
    name2->del(n - 9, 9);
    n -= 9;
  }

  // search for the font
  fi = nullptr;
  for (std::size_t i = 0; i < fonts->size(); ++i) {
    fi = (*fonts)[i];
    if (fi->match(name2, bold, italic, oblique, fixedWidth)) {
      break;
    }
    fi = nullptr;
  }
  if (!fi && !exact && bold) {
    // try ignoring the bold flag
    for (std::size_t i = 0; i < fonts->size(); ++i) {
      fi = (*fonts)[i];
      if (fi->match(name2, false, italic)) {
	break;
      }
      fi = nullptr;
    }
  }
  if (!fi && !exact && (bold || italic)) {
    // try ignoring the bold and italic flags
    for (std::size_t i = 0; i < fonts->size(); ++i) {
      fi = (*fonts)[i];
      if (fi->match(name2, false, false)) {
	break;
      }
      fi = nullptr;
    }
  }

  delete name2;
  return fi;
}


#define globalParamsLocker()	std::unique_lock<std::recursive_mutex> locker(mutex)
#define unicodeMapCacheLocker()	std::unique_lock<std::recursive_mutex> locker(unicodeMapCacheMutex)
#define cMapCacheLocker()	std::unique_lock<std::recursive_mutex> locker(cMapCacheMutex)

//------------------------------------------------------------------------
// parsing
//------------------------------------------------------------------------

GlobalParams::GlobalParams(const char *customPopplerDataDir)
  : popplerDataDir(customPopplerDataDir)
{
  initBuiltinFontTables();

  // scan the encoding in reverse because we want the lowest-numbered
  // index for each char name ('space' is encoded twice)
  macRomanReverseMap = new NameToCharCode();
  for (int i = 255; i >= 0; --i) {
    if (macRomanEncoding[i]) {
      macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i);
    }
  }

  nameToUnicodeZapfDingbats = new NameToCharCode();
  nameToUnicodeText = new NameToCharCode();
  toUnicodeDirs = new std::vector<GooString*>();
  sysFonts = new SysFontList();
  psExpandSmaller = false;
  psShrinkLarger = true;
  psLevel = psLevel2;
  textEncoding = new GooString("UTF-8");
#if defined(_WIN32)
  textEOL = eolDOS;
#else
  textEOL = eolUnix;
#endif
  textPageBreaks = true;
  enableFreeType = true;
  overprintPreview = false;
  printCommands = false;
  profileCommands = false;
  errQuiet = false;

  cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
  unicodeToUnicodeCache =
      new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize);
  unicodeMapCache = new UnicodeMapCache();
  cMapCache = new CMapCache();

  baseFontsInitialized = false;

  // set up the initial nameToUnicode tables
  for (int i = 0; nameToUnicodeZapfDingbatsTab[i].name; ++i) {
    nameToUnicodeZapfDingbats->add(nameToUnicodeZapfDingbatsTab[i].name, nameToUnicodeZapfDingbatsTab[i].u);
  }

  for (int i = 0; nameToUnicodeTextTab[i].name; ++i) {
    nameToUnicodeText->add(nameToUnicodeTextTab[i].name, nameToUnicodeTextTab[i].u);
  }

  // set up the residentUnicodeMaps table
  residentUnicodeMaps.reserve(6);
  UnicodeMap map = {"Latin1", false, latin1UnicodeMapRanges, latin1UnicodeMapLen};
  residentUnicodeMaps.emplace(map.getEncodingName()->toStr(), std::move(map));
  map = {"ASCII7", false, ascii7UnicodeMapRanges, ascii7UnicodeMapLen};
  residentUnicodeMaps.emplace(map.getEncodingName()->toStr(), std::move(map));
  map = {"Symbol", false, symbolUnicodeMapRanges, symbolUnicodeMapLen};
  residentUnicodeMaps.emplace(map.getEncodingName()->toStr(), std::move(map));
  map = {"ZapfDingbats", false, zapfDingbatsUnicodeMapRanges, zapfDingbatsUnicodeMapLen};
  residentUnicodeMaps.emplace(map.getEncodingName()->toStr(), std::move(map));
  map = {"UTF-8", true, &mapUTF8};
  residentUnicodeMaps.emplace(map.getEncodingName()->toStr(), std::move(map));
  map = {"UTF-16", true, &mapUTF16};
  residentUnicodeMaps.emplace(map.getEncodingName()->toStr(), std::move(map));

  scanEncodingDirs();
}

void GlobalParams::scanEncodingDirs() {
  GDir *dir;
  GDirEntry *entry;
  const char *dataRoot = popplerDataDir ? popplerDataDir : POPPLER_DATADIR;
  
  // allocate buffer large enough to append "/nameToUnicode"
  size_t bufSize = strlen(dataRoot) + strlen("/nameToUnicode") + 1;
  char *dataPathBuffer = new char[bufSize];
  
  snprintf(dataPathBuffer, bufSize, "%s/nameToUnicode", dataRoot);
  dir = new GDir(dataPathBuffer, true);
  while (entry = dir->getNextEntry(), entry != nullptr) {
    if (!entry->isDir()) {
      parseNameToUnicode(entry->getFullPath());
    }
    delete entry;
  }
  delete dir;

  snprintf(dataPathBuffer, bufSize, "%s/cidToUnicode", dataRoot);
  dir = new GDir(dataPathBuffer, false);
  while (entry = dir->getNextEntry(), entry != nullptr) {
    addCIDToUnicode(entry->getName(), entry->getFullPath());
    delete entry;
  }
  delete dir;

  snprintf(dataPathBuffer, bufSize, "%s/unicodeMap", dataRoot);
  dir = new GDir(dataPathBuffer, false);
  while (entry = dir->getNextEntry(), entry != nullptr) {
    addUnicodeMap(entry->getName(), entry->getFullPath());
    delete entry;
  }
  delete dir;

  snprintf(dataPathBuffer, bufSize, "%s/cMap", dataRoot);
  dir = new GDir(dataPathBuffer, false);
  while (entry = dir->getNextEntry(), entry != nullptr) {
    addCMapDir(entry->getName(), entry->getFullPath());
    toUnicodeDirs->push_back(entry->getFullPath()->copy());
    delete entry;
  }
  delete dir;
  
  delete[] dataPathBuffer;
}

void GlobalParams::parseNameToUnicode(const GooString *name) {
  char *tok1, *tok2;
  FILE *f;
  char buf[256];
  int line;
  Unicode u;
  char *tokptr;

  if (!(f = openFile(name->c_str(), "r"))) {
    error(errIO, -1, "Couldn't open 'nameToUnicode' file '{0:t}'",
	  name);
    return;
  }
  line = 1;
  while (getLine(buf, sizeof(buf), f)) {
    tok1 = strtok_r(buf, " \t\r\n", &tokptr);
    tok2 = strtok_r(nullptr, " \t\r\n", &tokptr);
    if (tok1 && tok2) {
      sscanf(tok1, "%x", &u);
      nameToUnicodeText->add(tok2, u);
    } else {
      error(errConfig, -1, "Bad line in 'nameToUnicode' file ({0:t}:{1:d})",
	    name, line);
    }
    ++line;
  }
  fclose(f);
}

void GlobalParams::addCIDToUnicode(const GooString *collection, const GooString *fileName) {
  cidToUnicodes[collection->toStr()] = fileName->toStr();
}

void GlobalParams::addUnicodeMap(const GooString *encodingName, const GooString *fileName) {
  unicodeMaps[encodingName->toStr()] = fileName->toStr();
}

void GlobalParams::addCMapDir(const GooString *collection, const GooString *dir) {
  cMapDirs.emplace(collection->toStr(), dir->toStr());
}

bool GlobalParams::parseYesNo2(const char *token, bool *flag) {
  if (!strcmp(token, "yes")) {
    *flag = true;
  } else if (!strcmp(token, "no")) {
    *flag = false;
  } else {
    return false;
  }
  return true;
}

GlobalParams::~GlobalParams() {
  freeBuiltinFontTables();

  delete macRomanReverseMap;

  delete nameToUnicodeZapfDingbats;
  delete nameToUnicodeText;
  for (auto entry : *toUnicodeDirs) {
    delete entry;
  }
  delete toUnicodeDirs;
  delete sysFonts;
  delete textEncoding;

  delete cidToUnicodeCache;
  delete unicodeToUnicodeCache;
  delete unicodeMapCache;
  delete cMapCache;
}

//------------------------------------------------------------------------
// accessors
//------------------------------------------------------------------------

CharCode GlobalParams::getMacRomanCharCode(char *charName) {
  // no need to lock - macRomanReverseMap is constant
  return macRomanReverseMap->lookup(charName);
}

Unicode GlobalParams::mapNameToUnicodeAll(const char *charName) {
  // no need to lock - nameToUnicodeZapfDingbats and nameToUnicodeText are constant
  Unicode u = nameToUnicodeZapfDingbats->lookup(charName);
  if (!u)
    u = nameToUnicodeText->lookup(charName);
  return u;
}

Unicode GlobalParams::mapNameToUnicodeText(const char *charName) {
  // no need to lock - nameToUnicodeText is constant
  return nameToUnicodeText->lookup(charName);
}

UnicodeMap *GlobalParams::getResidentUnicodeMap(const GooString *encodingName) {
  UnicodeMap *map = nullptr;

  globalParamsLocker();
  const auto unicodeMap = residentUnicodeMaps.find(encodingName->toStr());
  if (unicodeMap != residentUnicodeMaps.end()) {
    map = &unicodeMap->second;
    map->incRefCnt();
  }

  return map;
}

FILE *GlobalParams::getUnicodeMapFile(const GooString *encodingName) {
  FILE *file = nullptr;

  globalParamsLocker();
  const auto unicodeMap = unicodeMaps.find(encodingName->toStr());
  if (unicodeMap != unicodeMaps.end()) {
    file = openFile(unicodeMap->second.c_str(), "r");
  }

  return file;
}

FILE *GlobalParams::findCMapFile(const GooString *collection, const GooString *cMapName) {
  FILE *file = nullptr;

  globalParamsLocker();
  const auto collectionCMapDirs = cMapDirs.equal_range(collection->toStr());
  for (auto cMapDir = collectionCMapDirs.first; cMapDir != collectionCMapDirs.second; ++cMapDir) {
    auto* const path = new GooString(cMapDir->second);
    appendToPath(path, cMapName->c_str());
    file = openFile(path->c_str(), "r");
    delete path;
    if (file) {
      break;
    }
  }

  return file;
}

FILE *GlobalParams::findToUnicodeFile(const GooString *name) {
  GooString *dir, *fileName;
  FILE *f;

  globalParamsLocker();
  for (std::size_t i = 0; i < toUnicodeDirs->size(); ++i) {
    dir = (*toUnicodeDirs)[i];
    fileName = appendToPath(dir->copy(), name->c_str());
    f = openFile(fileName->c_str(), "r");
    delete fileName;
    if (f) {
      return f;
    }
  }
  return nullptr;
}

#ifdef WITH_FONTCONFIGURATION_FONTCONFIG
static bool findModifier(const char *name, const char *modifier, const char **start)
{
  const char *match;

  if (name == nullptr)
    return false;

  match = strstr(name, modifier);
  if (match) {
    if (*start == nullptr || match < *start)
      *start = match;
    return true;
  }
  else {
    return false;
  }
}

static const char *getFontLang(GfxFont *font)
{
  const char *lang;

  // find the language we want the font to support
  if (font->isCIDFont())
  {
    const GooString *collection = ((GfxCIDFont *)font)->getCollection();
    if (collection)
    {
      if (strcmp(collection->c_str(), "Adobe-GB1") == 0)
        lang = "zh-cn"; // Simplified Chinese
      else if (strcmp(collection->c_str(), "Adobe-CNS1") == 0)
        lang = "zh-tw"; // Traditional Chinese
      else if (strcmp(collection->c_str(), "Adobe-Japan1") == 0)
        lang = "ja"; // Japanese
      else if (strcmp(collection->c_str(), "Adobe-Japan2") == 0)
        lang = "ja"; // Japanese
      else if (strcmp(collection->c_str(), "Adobe-Korea1") == 0)
        lang = "ko"; // Korean
      else if (strcmp(collection->c_str(), "Adobe-UCS") == 0)
        lang = "xx";
      else if (strcmp(collection->c_str(), "Adobe-Identity") == 0)
        lang = "xx";
      else
      {
        error(errUnimplemented, -1, "Unknown CID font collection, please report to poppler bugzilla.");
        lang = "xx";
      }
    }
    else lang = "xx";
  }
  else lang = "xx";
  return lang;
}

static FcPattern *buildFcPattern(GfxFont *font, const GooString *base14Name)
{
  int weight = -1,
      slant = -1,
      width = -1,
      spacing = -1;
  const char *family;
  const char *start;
  FcPattern *p;

  // this is all heuristics will be overwritten if font had proper info
  char *fontName = strdup(((base14Name == nullptr) ? font->getName() : base14Name)->c_str());

  const char *modifiers = strchr (fontName, ',');
  if (modifiers == nullptr)
    modifiers = strchr (fontName, '-');

  // remove the - from the names, for some reason, Fontconfig does not
  // understand "MS-Mincho" but does with "MS Mincho"
  const int len = strlen(fontName);
  for (int i = 0; i < len; i++)
    fontName[i] = (fontName[i] == '-' ? ' ' : fontName[i]);

  start = nullptr;
  findModifier(modifiers, "Regular", &start);
  findModifier(modifiers, "Roman", &start);
  
  if (findModifier(modifiers, "Oblique", &start))
    slant = FC_SLANT_OBLIQUE;
  if (findModifier(modifiers, "Italic", &start))
    slant = FC_SLANT_ITALIC;
  if (findModifier(modifiers, "Bold", &start))
    weight = FC_WEIGHT_BOLD;
  if (findModifier(modifiers, "Light", &start))
    weight = FC_WEIGHT_LIGHT;
  if (findModifier(modifiers, "Medium", &start))
    weight = FC_WEIGHT_MEDIUM;
  if (findModifier(modifiers, "Condensed", &start))
    width = FC_WIDTH_CONDENSED;
  
  if (start) {
    // There have been "modifiers" in the name, crop them to obtain
    // the family name
    family = strndup(fontName, modifiers - fontName);
    free(fontName);
    fontName = nullptr;
  }
  else {
    family = fontName;
    fontName = nullptr;
  }
  
  // use font flags
  if (font->isFixedWidth())
    spacing = FC_MONO;
  if (font->isBold())
    weight = FC_WEIGHT_BOLD;
  if (font->isItalic())
    slant = FC_SLANT_ITALIC;
  
  bool freeFamily = true;
  // if the FontDescriptor specified a family name use it
  if (font->getFamily()) {
    free((char*)family);
    family = font->getFamily()->c_str();
    freeFamily = false;
  }
  
  // if the FontDescriptor specified a weight use it
  switch (font -> getWeight())
  {
    case GfxFont::W100: weight = FC_WEIGHT_EXTRALIGHT; break; 
    case GfxFont::W200: weight = FC_WEIGHT_LIGHT; break; 
    case GfxFont::W300: weight = FC_WEIGHT_BOOK; break; 
    case GfxFont::W400: weight = FC_WEIGHT_NORMAL; break; 
    case GfxFont::W500: weight = FC_WEIGHT_MEDIUM; break; 
    case GfxFont::W600: weight = FC_WEIGHT_DEMIBOLD; break; 
    case GfxFont::W700: weight = FC_WEIGHT_BOLD; break; 
    case GfxFont::W800: weight = FC_WEIGHT_EXTRABOLD; break; 
    case GfxFont::W900: weight = FC_WEIGHT_BLACK; break; 
    default: break; 
  }
  
  // if the FontDescriptor specified a width use it
  switch (font -> getStretch())
  {
    case GfxFont::UltraCondensed: width = FC_WIDTH_ULTRACONDENSED; break; 
    case GfxFont::ExtraCondensed: width = FC_WIDTH_EXTRACONDENSED; break; 
    case GfxFont::Condensed: width = FC_WIDTH_CONDENSED; break; 
    case GfxFont::SemiCondensed: width = FC_WIDTH_SEMICONDENSED; break; 
    case GfxFont::Normal: width = FC_WIDTH_NORMAL; break; 
    case GfxFont::SemiExpanded: width = FC_WIDTH_SEMIEXPANDED; break; 
    case GfxFont::Expanded: width = FC_WIDTH_EXPANDED; break; 
    case GfxFont::ExtraExpanded: width = FC_WIDTH_EXTRAEXPANDED; break; 
    case GfxFont::UltraExpanded: width = FC_WIDTH_ULTRAEXPANDED; break; 
    default: break; 
  }
  
  const char *lang = getFontLang(font);
  
  p = FcPatternBuild(nullptr,
                    FC_FAMILY, FcTypeString, family,
                    FC_LANG, FcTypeString, lang,
                    NULL);
  if (slant != -1) FcPatternAddInteger(p, FC_SLANT, slant);
  if (weight != -1) FcPatternAddInteger(p, FC_WEIGHT, weight);
  if (width != -1) FcPatternAddInteger(p, FC_WIDTH, width);
  if (spacing != -1) FcPatternAddInteger(p, FC_SPACING, spacing);

  if (freeFamily)
    free((char*)family);
  return p;
}
#endif

GooString *GlobalParams::findFontFile(const GooString *fontName) {
  GooString *path = nullptr;

  setupBaseFonts(nullptr);
  globalParamsLocker();
  const auto fontFile = fontFiles.find(fontName->toStr());
  if (fontFile != fontFiles.end()) {
    path = new GooString(fontFile->second);
  }

  return path;
}

/* if you can't or don't want to use Fontconfig, you need to implement
   this function for your platform. For Windows, it's in GlobalParamsWin.cc
*/
#ifdef WITH_FONTCONFIGURATION_FONTCONFIG
// not needed for fontconfig
void GlobalParams::setupBaseFonts(char *) {
}

GooString *GlobalParams::findBase14FontFile(const GooString *base14Name, GfxFont *font) {
  SysFontType type;
  int fontNum;
  
  return findSystemFontFile(font, &type, &fontNum, nullptr, base14Name);
}

GooString *GlobalParams::findSystemFontFile(GfxFont *font,
					  SysFontType *type,
					  int *fontNum, GooString *substituteFontName, const GooString *base14Name) {
  SysFontInfo *fi = nullptr;
  FcPattern *p=nullptr;
  GooString *path = nullptr;
  const GooString *fontName = font->getName();
  GooString substituteName;
  if (!fontName) return nullptr;

  globalParamsLocker();

  if ((fi = sysFonts->find(fontName, font->isFixedWidth(), true))) {
    path = fi->path->copy();
    *type = fi->type;
    *fontNum = fi->fontNum;
    substituteName.Set(fi->substituteName->c_str());
  } else {
    FcChar8* s;
    char * ext;
    FcResult res;
    FcFontSet *set;
    int i;
    FcLangSet *lb = nullptr;
    p = buildFcPattern(font, base14Name);

    if (!p)
      goto fin;
    FcConfigSubstitute(nullptr, p, FcMatchPattern);
    FcDefaultSubstitute(p);
    set = FcFontSort(nullptr, p, FcFalse, nullptr, &res);
    if (!set)
      goto fin;

    // find the language we want the font to support
    const char *lang = getFontLang(font);
    if (strcmp(lang,"xx") != 0) {
      lb = FcLangSetCreate();
      FcLangSetAdd(lb,(FcChar8 *)lang);
    }

    /*
      scan twice.
      first: fonts support the language
      second: all fonts (fall back)
    */
    while (fi == nullptr)
    {
      for (i = 0; i < set->nfont; ++i)
      {
	res = FcPatternGetString(set->fonts[i], FC_FILE, 0, &s);
	if (res != FcResultMatch || !s)
	  continue;
	if (lb != nullptr) {
	  FcLangSet *l;
	  res = FcPatternGetLangSet(set->fonts[i], FC_LANG, 0, &l);
	  if (res != FcResultMatch || !FcLangSetContains(l,lb)) {
	    continue;
	  }
	}
	FcChar8* s2;
        res = FcPatternGetString(set->fonts[i], FC_FULLNAME, 0, &s2);
        if (res == FcResultMatch && s2) {
          substituteName.Set((char*)s2);
        } else {
          // fontconfig does not extract fullname for some fonts
          // create the fullname from family and style
          res = FcPatternGetString(set->fonts[i], FC_FAMILY, 0, &s2);
          if (res == FcResultMatch && s2) {
            substituteName.Set((char*)s2);
            res = FcPatternGetString(set->fonts[i], FC_STYLE, 0, &s2);
            if (res == FcResultMatch && s2) {
              GooString *style = new GooString((char*)s2);
              if (style->cmp("Regular") != 0) {
                substituteName.append(" ");
                substituteName.append(style);
              }
              delete style;
            }
          }
        }
	ext = strrchr((char*)s,'.');
	if (!ext)
	  continue;
	if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4) || !strncasecmp(ext, ".otf", 4))
	{
	  int weight, slant;
	  bool bold = font->isBold();
	  bool italic = font->isItalic();
	  bool oblique = false;
	  FcPatternGetInteger(set->fonts[i], FC_WEIGHT, 0, &weight);
	  FcPatternGetInteger(set->fonts[i], FC_SLANT, 0, &slant);
	  if (weight == FC_WEIGHT_DEMIBOLD || weight == FC_WEIGHT_BOLD 
	      || weight == FC_WEIGHT_EXTRABOLD || weight == FC_WEIGHT_BLACK)
	  {
	    bold = true;
	  }
	  if (slant == FC_SLANT_ITALIC)
	    italic = true;
	  if (slant == FC_SLANT_OBLIQUE)
	    oblique = true;
	  *fontNum = 0;
	  *type = (!strncasecmp(ext,".ttc",4)) ? sysFontTTC : sysFontTTF;
	  FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, fontNum);
	  fi = new SysFontInfo(fontName->copy(), bold, italic, oblique, font->isFixedWidth(),
			       new GooString((char*)s), *type, *fontNum, substituteName.copy());
	  sysFonts->addFcFont(fi);
	  path = new GooString((char*)s);
	}
	else if (!strncasecmp(ext,".pfa",4) || !strncasecmp(ext,".pfb",4)) 
	{
	  int weight, slant;
	  bool bold = font->isBold();
	  bool italic = font->isItalic();
	  bool oblique = false;
	  FcPatternGetInteger(set->fonts[i], FC_WEIGHT, 0, &weight);
	  FcPatternGetInteger(set->fonts[i], FC_SLANT, 0, &slant);
	  if (weight == FC_WEIGHT_DEMIBOLD || weight == FC_WEIGHT_BOLD 
	      || weight == FC_WEIGHT_EXTRABOLD || weight == FC_WEIGHT_BLACK)
	  {
		bold = true;
	  }
	  if (slant == FC_SLANT_ITALIC)
	    italic = true;
	  if (slant == FC_SLANT_OBLIQUE)
	    oblique = true;
	  *fontNum = 0;
	  *type = (!strncasecmp(ext,".pfa",4)) ? sysFontPFA : sysFontPFB;
	  FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, fontNum);
	  fi = new SysFontInfo(fontName->copy(), bold, italic, oblique, font->isFixedWidth(),
			       new GooString((char*)s), *type, *fontNum, substituteName.copy());
	  sysFonts->addFcFont(fi);
	  path = new GooString((char*)s);
	}
	else
	  continue;
	break;
      }
      if (lb != nullptr) {
        FcLangSetDestroy(lb);
        lb = nullptr;
      } else {
        /* scan all fonts of the list */
        break;
      }
    }
    FcFontSetDestroy(set);
  }
  if (path == nullptr && (fi = sysFonts->find(fontName, font->isFixedWidth(), false))) {
    path = fi->path->copy();
    *type = fi->type;
    *fontNum = fi->fontNum;
  }
  if (substituteFontName) {
    substituteFontName->Set(substituteName.c_str());
  }
fin:
  if (p)
    FcPatternDestroy(p);

  return path;
}

#elif WITH_FONTCONFIGURATION_WIN32
#include "GlobalParamsWin.cc"

GooString *GlobalParams::findBase14FontFile(const GooString *base14Name, GfxFont *font) {
  return findFontFile(base14Name);
}
#else
GooString *GlobalParams::findBase14FontFile(const GooString *base14Name, GfxFont *font) {
  return findFontFile(base14Name);
}

static struct {
  const char *name;
  const char *t1FileName;
  const char *ttFileName;
} displayFontTab[] = {
  {"Courier",               "n022003l.pfb", "cour.ttf"},
  {"Courier-Bold",          "n022004l.pfb", "courbd.ttf"},
  {"Courier-BoldOblique",   "n022024l.pfb", "courbi.ttf"},
  {"Courier-Oblique",       "n022023l.pfb", "couri.ttf"},
  {"Helvetica",             "n019003l.pfb", "arial.ttf"},
  {"Helvetica-Bold",        "n019004l.pfb", "arialbd.ttf"},
  {"Helvetica-BoldOblique", "n019024l.pfb", "arialbi.ttf"},
  {"Helvetica-Oblique",     "n019023l.pfb", "ariali.ttf"},
  {"Symbol",                "s050000l.pfb", nullptr},
  {"Times-Bold",            "n021004l.pfb", "timesbd.ttf"},
  {"Times-BoldItalic",      "n021024l.pfb", "timesbi.ttf"},
  {"Times-Italic",          "n021023l.pfb", "timesi.ttf"},
  {"Times-Roman",           "n021003l.pfb", "times.ttf"},
  {"ZapfDingbats",          "d050000l.pfb", nullptr},
  {nullptr, nullptr, nullptr}
};

static const char *displayFontDirs[] = {
  "/usr/share/ghostscript/fonts",
  "/usr/local/share/ghostscript/fonts",
  "/usr/share/fonts/default/Type1",
  "/usr/share/fonts/default/ghostscript",
  "/usr/share/fonts/type1/gsfonts",
  nullptr
};

void GlobalParams::setupBaseFonts(char *dir) {
  GooString *fontName;
  GooString *fileName;
  FILE *f;
  int i, j;

  for (i = 0; displayFontTab[i].name; ++i) {
    if (fontFiles.count(displayFontTab[i].name) > 0) {
      continue;
    }
    fontName = new GooString(displayFontTab[i].name);
    fileName = nullptr;
    if (dir) {
      fileName = appendToPath(new GooString(dir), displayFontTab[i].t1FileName);
      if ((f = openFile(fileName->c_str(), "rb"))) {
	      fclose(f);
      } else {
	      delete fileName;
	      fileName = nullptr;
      }
    }
    for (j = 0; !fileName && displayFontDirs[j]; ++j) {
      fileName = appendToPath(new GooString(displayFontDirs[j]),
			      displayFontTab[i].t1FileName);
      if ((f = openFile(fileName->c_str(), "rb"))) {
	      fclose(f);
      } else {
	      delete fileName;
	      fileName = nullptr;
      }
    }
    if (!fileName) {
      error(errConfig, -1, "No display font for '{0:s}'",
	    displayFontTab[i].name);
      delete fontName;
      continue;
    }
    addFontFile(fontName, fileName);
  }

}

GooString *GlobalParams::findSystemFontFile(GfxFont *font,
					  SysFontType *type,
					  int *fontNum, GooString * /*substituteFontName*/,
					  const GooString * /*base14Name*/) {
  SysFontInfo *fi;
  GooString *path;

  const GooString *fontName = font->getName();
  if (!fontName) return nullptr;

  path = nullptr;
  globalParamsLocker();
  if ((fi = sysFonts->find(fontName, font->isFixedWidth(), false))) {
    path = fi->path->copy();
    *type = fi->type;
    *fontNum = fi->fontNum;
  }

  return path;
}
#endif

bool GlobalParams::getPSExpandSmaller() {
  globalParamsLocker();
  return psExpandSmaller;
}

bool GlobalParams::getPSShrinkLarger() {
  globalParamsLocker();
  return psShrinkLarger;
}

PSLevel GlobalParams::getPSLevel() {
  globalParamsLocker();
  return psLevel;
}

GooString *GlobalParams::getTextEncodingName() {
  globalParamsLocker();
  return textEncoding->copy();
}

EndOfLineKind GlobalParams::getTextEOL() {
  globalParamsLocker();
  return textEOL;
}

bool GlobalParams::getTextPageBreaks() {
  globalParamsLocker();
  return textPageBreaks;
}

bool GlobalParams::getEnableFreeType() {
  globalParamsLocker();
  return enableFreeType;
}

bool GlobalParams::getPrintCommands() {
  globalParamsLocker();
  return printCommands;
}

bool GlobalParams::getProfileCommands() {
  globalParamsLocker();
  return profileCommands;
}

bool GlobalParams::getErrQuiet() {
  // no locking -- this function may get called from inside a locked
  // section
  return errQuiet;
}

CharCodeToUnicode *GlobalParams::getCIDToUnicode(GooString *collection) {
  CharCodeToUnicode *ctu;

  globalParamsLocker();
  if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
    const auto cidToUnicode = cidToUnicodes.find(collection->toStr());
    if (cidToUnicode != cidToUnicodes.end()) {
      if((ctu = CharCodeToUnicode::parseCIDToUnicode(cidToUnicode->second.c_str(), collection))) {
        cidToUnicodeCache->add(ctu);
      }
    }
  }

  return ctu;
}

UnicodeMap *GlobalParams::getUnicodeMap(GooString *encodingName) {
  return getUnicodeMap2(encodingName);
}

UnicodeMap *GlobalParams::getUnicodeMap2(GooString *encodingName) {
  UnicodeMap *map;

  if (!(map = getResidentUnicodeMap(encodingName))) {
    unicodeMapCacheLocker();
    map = unicodeMapCache->getUnicodeMap(encodingName);
  }

  return map;
}

CMap *GlobalParams::getCMap(const GooString *collection, GooString *cMapName, Stream *stream) {
  cMapCacheLocker();
  return cMapCache->getCMap(collection, cMapName, stream);
}

UnicodeMap *GlobalParams::getTextEncoding() {
  return getUnicodeMap2(textEncoding);
}

std::vector<GooString*> *GlobalParams::getEncodingNames()
{
  auto* const result = new std::vector<GooString*>;
  for (const auto& unicodeMap : residentUnicodeMaps) {
    result->push_back(new GooString(unicodeMap.first));
  }
  for (const auto& unicodeMap : unicodeMaps) {
    result->push_back(new GooString(unicodeMap.first));
  }
  return result;
}

//------------------------------------------------------------------------
// functions to set parameters
//------------------------------------------------------------------------

void GlobalParams::addFontFile(GooString *fontName, GooString *path) {
  globalParamsLocker();
  fontFiles[fontName->toStr()] = path->toStr();
}

void GlobalParams::setPSExpandSmaller(bool expand) {
  globalParamsLocker();
  psExpandSmaller = expand;
}

void GlobalParams::setPSShrinkLarger(bool shrink) {
  globalParamsLocker();
  psShrinkLarger = shrink;
}

void GlobalParams::setPSLevel(PSLevel level) {
  globalParamsLocker();
  psLevel = level;
}

void GlobalParams::setTextEncoding(char *encodingName) {
  globalParamsLocker();
  delete textEncoding;
  textEncoding = new GooString(encodingName);
}

bool GlobalParams::setTextEOL(char *s) {
  globalParamsLocker();
  if (!strcmp(s, "unix")) {
    textEOL = eolUnix;
  } else if (!strcmp(s, "dos")) {
    textEOL = eolDOS;
  } else if (!strcmp(s, "mac")) {
    textEOL = eolMac;
  } else {
    return false;
  }
  return true;
}

void GlobalParams::setTextPageBreaks(bool pageBreaks) {
  globalParamsLocker();
  textPageBreaks = pageBreaks;
}

bool GlobalParams::setEnableFreeType(char *s) {
  globalParamsLocker();
  return parseYesNo2(s, &enableFreeType);
}

void GlobalParams::setOverprintPreview(bool overprintPreviewA) {
  globalParamsLocker();
  overprintPreview = overprintPreviewA;
}

void GlobalParams::setPrintCommands(bool printCommandsA) {
  globalParamsLocker();
  printCommands = printCommandsA;
}

void GlobalParams::setProfileCommands(bool profileCommandsA) {
  globalParamsLocker();
  profileCommands = profileCommandsA;
}

void GlobalParams::setErrQuiet(bool errQuietA) {
  globalParamsLocker();
  errQuiet = errQuietA;
}
