// Copyright (C) 2000-2007, Luca Padovani <padovani@sti.uniurb.it>. // // This file is part of GtkMathView, a flexible, high-quality rendering // engine for MathML documents. // // GtkMathView is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as published // by the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // GtkMathView is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. #include <t1lib.h> #include <config.h> #include <map> #include <string> #include <stdlib.h> #include <iostream> #include <list> #include "String.hh" #include "T1_FontDataBase.hh" #include "FontDataBase.hh" #include "AbstractLogger.hh" #include "Configuration.hh" T1_FontDataBase::T1_DataBase::T1_DataBase(String& name, int i, int initVal) : fontName(name), id(i) { for (int i = 0; i < 256; i++) used[i] = initVal; } T1_FontDataBase::T1_FontDataBase(const SmartPtr<AbstractLogger>& l, const SmartPtr<class Configuration>& conf, bool sub) : FontDataBase(), logger(l), subset(sub) { int result; std::vector<String> s = conf->getStringList("default/t1lib/t1-font-path"); for (std::vector<String>::iterator p = s.begin(); p != s.end(); p++) { result = T1_AddToFileSearchPath(T1_PFAB_PATH, T1_APPEND_PATH, const_cast<char*>(p->c_str())); if (result != 0) { logger->out(LOG_ERROR, "could not add FontDataBase: %s", p->c_str()); exit (-1); } } void* res = T1_InitLib(LOGFILE | IGNORE_FONTDATABASE); if (res == NULL) { logger->out(LOG_ERROR, "could not initialize t1lib"); exit (-1); } } T1_FontDataBase::~T1_FontDataBase() { int res = T1_CloseLib(); if (res != 0) logger->out(LOG_INFO, "t1lib could not uninitialize itself properly, please consult the log file"); } SmartPtr<T1_FontDataBase> T1_FontDataBase::create(const SmartPtr<AbstractLogger>& l, const SmartPtr<class Configuration>& conf, bool subset) { return new T1_FontDataBase(l, conf, subset); } int T1_FontDataBase::getFontId(const String& fontName, float fontSize) { int n = T1_GetNoFonts(); String fileName = toLowerCase(fontName) + ".pfb"; int i; for (i = 0; i < n && (strcmp(fileName.c_str(), T1_GetFontFileName(i))); i++); if (i == n) { logger->out(LOG_INFO, "adding font file '%s' to the font database", fileName.c_str()); i = T1_AddFont(const_cast<char*>(fileName.c_str())); if (i < 0) { logger->out(LOG_WARNING, "could not load Type1 font file `%s'", fileName.c_str()); exit (-1); } logger->out(LOG_INFO, "loading font ID: %d", i); T1_LoadFont(i); if (subset) // subset T1_dB.push_back(T1_DataBase(fileName, i, 0)); else // embed T1_dB.push_back(T1_DataBase(fileName, i, 1)); } else logger->out(LOG_DEBUG, "font '%s' exists in the fontDataBase", fileName.c_str()); int id = FontDataBase::getFontId(fontName, fontSize); return (id); } void T1_FontDataBase::dumpFontTable(std::ostream& os) const { os << "%%DocumentSuppliedResources: font" << std::endl; for (std::list<T1_DataBase>::const_iterator p = T1_dB.begin(); p != T1_dB.end(); p++) os << "%%+ font " << p->fontName << std::endl; os << std::endl; os << "%%BeginSetup" << std::endl; for (std::list<T1_DataBase>::const_iterator p = T1_dB.begin(); p != T1_dB.end(); p++) { logger->out(LOG_DEBUG, "subset font `%s'", (p->fontName).c_str()); unsigned int count = 0; for (unsigned int i = 0; i < 256; i++) if (p->used[i]) count++; logger->out(LOG_DEBUG, "subsetting %d chars", count); const char* use = (char*)(p->used); unsigned long bufSize; char* dump = T1_SubsetFont(p -> id, const_cast<char*>(use), T1_SUBSET_DEFAULT | T1_SUBSET_SKIP_REENCODE, 64, 16384, &bufSize); os << "%%BeginResource: font " << p->fontName << std::endl; os.write(dump, bufSize); os << "%%EndResource" << std::endl; logger->out(LOG_DEBUG, "done!"); free(dump); } os << "%%EndSetup" << std::endl << std::endl; FontDataBase::dumpFontTable(os); } void T1_FontDataBase::recallFont(const int id, std::ostringstream& body) { FontDataBase::recallFont(id, body); } void T1_FontDataBase::usedChar(const String& content, const String& family) { if (subset) { String fileName = toLowerCase(family) + ".pfb"; std::list<T1_DataBase>::iterator it; for (it = T1_dB.begin(); (it->fontName) != fileName; it++); for (String::const_iterator i = content.begin(); i != content.end(); i++) it->used[(unsigned int)(*i)] = 1; } }