//========================================================================
//
// 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, 2018 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>
//
// 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/GooList.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

  GooList *fonts;			// [SysFontInfo]
};

SysFontList::SysFontList() {
  fonts = new GooList();
}

SysFontList::~SysFontList() {
  deleteGooList<SysFontInfo>(fonts);
}

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

  name2 = name->copy();

  // remove space, comma, dash chars
  i = 0;
  while (i < name2->getLength()) {
    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 (i = 0; i < fonts->getLength(); ++i) {
    fi = (SysFontInfo *)fonts->get(i);
    if (fi->match(name2, bold, italic, oblique, fixedWidth)) {
      break;
    }
    fi = nullptr;
  }
  if (!fi && !exact && bold) {
    // try ignoring the bold flag
    for (i = 0; i < fonts->getLength(); ++i) {
      fi = (SysFontInfo *)fonts->get(i);
      if (fi->match(name2, false, italic)) {
	break;
      }
      fi = nullptr;
    }
  }
  if (!fi && !exact && (bold || italic)) {
    // try ignoring the bold and italic flags
    for (i = 0; i < fonts->getLength(); ++i) {
      fi = (SysFontInfo *)fonts->get(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 GooList();
  sysFonts = new SysFontList();
  psExpandSmaller = false;
  psShrinkLarger = true;
  psLevel = psLevel2;
  textEncoding = new GooString("UTF-8");
#if defined(_WIN32)
  textEOL = eolDOS;
#elif defined(MACOS)
  textEOL = eolMac;
#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;
  deleteGooList<GooString>(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 cMapDirs = this->cMapDirs.equal_range(collection->toStr());
  for (auto cMapDir = cMapDirs.first; cMapDir != cMapDirs.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;
  int i;

  globalParamsLocker();
  for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
    dir = (GooString *)toUnicodeDirs->get(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);
}

GooList *GlobalParams::getEncodingNames()
{
  auto* const result = new GooList;
  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;
}
