//========================================================================
//
// SplashFontEngine.cc
//
//========================================================================

//========================================================================
//
// 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) 2006 Takashi Iwai <tiwai@suse.de>
// Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com>
// Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
// Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2011 Andreas Hartmetz <ahartmetz@gmail.com>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2015 Dmytro Morgun <lztoad@gmail.com>
// Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2018 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 <stdlib.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#  include <unistd.h>
#endif
#include <algorithm>

#include "goo/gmem.h"
#include "goo/GooString.h"
#include "SplashMath.h"
#include "SplashFTFontEngine.h"
#include "SplashFontFile.h"
#include "SplashFontFileID.h"
#include "SplashFont.h"
#include "SplashFontEngine.h"

#ifdef VMS
#if (__VMS_VER < 70000000)
extern "C" int unlink(char *filename);
#endif
#endif

#ifdef VMS
#if (__VMS_VER < 70000000)
extern "C" int unlink(char *filename);
#endif
#endif

//------------------------------------------------------------------------
// SplashFontEngine
//------------------------------------------------------------------------

SplashFontEngine::SplashFontEngine(
				   bool enableFreeType,
				   bool enableFreeTypeHinting,
				   bool enableSlightHinting,
				   bool aa) {
  std::fill(fontCache.begin(), fontCache.end(), nullptr);

  if (enableFreeType) {
    ftEngine = SplashFTFontEngine::init(aa, enableFreeTypeHinting, enableSlightHinting);
  } else {
    ftEngine = nullptr;
  }
}

SplashFontEngine::~SplashFontEngine() {
  for (auto font : fontCache) {
    delete font;
  }

  if (ftEngine) {
    delete ftEngine;
  }
}

SplashFontFile *SplashFontEngine::getFontFile(SplashFontFileID *id) {
  for (auto font : fontCache) {
    if (font) {
      SplashFontFile *fontFile = font->getFontFile();
      if (fontFile && fontFile->getID()->matches(id)) {
	return fontFile;
      }
    }
  }
  return nullptr;
}

SplashFontFile *SplashFontEngine::loadType1Font(SplashFontFileID *idA,
						SplashFontSrc *src,
						const char **enc) {
  SplashFontFile *fontFile = nullptr;

  if (ftEngine) {
    fontFile = ftEngine->loadType1Font(idA, src, enc);
  }

  // delete the (temporary) font file -- with Unix hard link
  // semantics, this will remove the last link; otherwise it will
  // return an error, leaving the file to be deleted later (if
  // loadXYZFont failed, the file will always be deleted)
  if (src->isFile)
    src->unref();

  return fontFile;
}

SplashFontFile *SplashFontEngine::loadType1CFont(SplashFontFileID *idA,
						 SplashFontSrc *src,
						 const char **enc) {
  SplashFontFile *fontFile = nullptr;

  if (ftEngine) {
    fontFile = ftEngine->loadType1CFont(idA, src, enc);
  }

  // delete the (temporary) font file -- with Unix hard link
  // semantics, this will remove the last link; otherwise it will
  // return an error, leaving the file to be deleted later (if
  // loadXYZFont failed, the file will always be deleted)
  if (src->isFile)
    src->unref();

  return fontFile;
}

SplashFontFile *SplashFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA,
						      SplashFontSrc *src,
						      const char **enc) {
  SplashFontFile *fontFile = nullptr;

  if (ftEngine) {
    fontFile = ftEngine->loadOpenTypeT1CFont(idA, src, enc);
  }

  // delete the (temporary) font file -- with Unix hard link
  // semantics, this will remove the last link; otherwise it will
  // return an error, leaving the file to be deleted later (if
  // loadXYZFont failed, the file will always be deleted)
  if (src->isFile)
    src->unref();

  return fontFile;
}

SplashFontFile *SplashFontEngine::loadCIDFont(SplashFontFileID *idA,
					      SplashFontSrc *src) {
  SplashFontFile *fontFile = nullptr;

  if (ftEngine) {
    fontFile = ftEngine->loadCIDFont(idA, src);
  }

  // delete the (temporary) font file -- with Unix hard link
  // semantics, this will remove the last link; otherwise it will
  // return an error, leaving the file to be deleted later (if
  // loadXYZFont failed, the file will always be deleted)
  if (src->isFile)
    src->unref();

  return fontFile;
}

SplashFontFile *SplashFontEngine::loadOpenTypeCFFFont(SplashFontFileID *idA,
						      SplashFontSrc *src,
                                                      int *codeToGID,
                                                      int codeToGIDLen) {
  SplashFontFile *fontFile = nullptr;

  if (ftEngine) {
    fontFile = ftEngine->loadOpenTypeCFFFont(idA, src, codeToGID, codeToGIDLen);
  }

  // delete the (temporary) font file -- with Unix hard link
  // semantics, this will remove the last link; otherwise it will
  // return an error, leaving the file to be deleted later (if
  // loadXYZFont failed, the file will always be deleted)
  if (src->isFile)
    src->unref();

  return fontFile;
}

SplashFontFile *SplashFontEngine::loadTrueTypeFont(SplashFontFileID *idA,
						   SplashFontSrc *src,
						   int *codeToGID,
						   int codeToGIDLen,
						   int faceIndex) {
  SplashFontFile *fontFile = nullptr;

  if (ftEngine) {
    fontFile = ftEngine->loadTrueTypeFont(idA, src,
                                        codeToGID, codeToGIDLen, faceIndex);
  }

  if (!fontFile) {
    gfree(codeToGID);
  }

  // delete the (temporary) font file -- with Unix hard link
  // semantics, this will remove the last link; otherwise it will
  // return an error, leaving the file to be deleted later (if
  // loadXYZFont failed, the file will always be deleted)
  if (src->isFile)
    src->unref();

  return fontFile;
}

bool SplashFontEngine::getAA() {
  return (ftEngine == nullptr) ? false : ftEngine->getAA();
}

void SplashFontEngine::setAA(bool aa) {
  if (ftEngine != nullptr) {
    ftEngine->setAA(aa);
  }
}

SplashFont *SplashFontEngine::getFont(SplashFontFile *fontFile,
				      const SplashCoord *textMat,
				      const SplashCoord *ctm) {
  SplashCoord mat[4];

  mat[0] = textMat[0] * ctm[0] + textMat[1] * ctm[2];
  mat[1] = -(textMat[0] * ctm[1] + textMat[1] * ctm[3]);
  mat[2] = textMat[2] * ctm[0] + textMat[3] * ctm[2];
  mat[3] = -(textMat[2] * ctm[1] + textMat[3] * ctm[3]);
  if (!splashCheckDet(mat[0], mat[1], mat[2], mat[3], 0.01)) {
    // avoid a singular (or close-to-singular) matrix
    mat[0] = 0.01;  mat[1] = 0;
    mat[2] = 0;     mat[3] = 0.01;
  }

  // Try to find the font in the cache
  auto fontIt = std::find_if(fontCache.begin(), fontCache.end(),
                             [&](const SplashFont* font){return font && font->matches(fontFile, mat, textMat);}
                            );

  // The requested font has been found in the cache
  if (fontIt != fontCache.end()) {
    std::rotate(fontCache.begin(), fontIt, fontIt+1);
    return fontCache[0];
  }

  // The requested font has not been found in the cache
  auto newFont = fontFile->makeFont(mat, textMat);
  if (fontCache.back()) {
    delete fontCache.back();
  }
  std::rotate(fontCache.begin(), fontCache.end()-1, fontCache.end());

  fontCache[0] = newFont;
  return fontCache[0];
}
