//========================================================================
//
// 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(
				   GBool enableFreeType,
				   GBool enableFreeTypeHinting,
				   GBool enableSlightHinting,
				   GBool 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;
}

GBool SplashFontEngine::getAA() {
  return (ftEngine == nullptr) ? gFalse : ftEngine->getAA();
}

void SplashFontEngine::setAA(GBool 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];
}
