You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
6.0 KiB
165 lines
6.0 KiB
// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- |
|
// fontMap.cpp |
|
// |
|
// Part of KDVI - A DVI previewer for the KDE desktop environment |
|
// |
|
// SPDX-FileCopyrightText: 2003 Stefan Kebekus |
|
// SPDX-License-Identifier: GPL-2.0-or-later |
|
|
|
#include <config.h> |
|
|
|
#ifdef HAVE_FREETYPE |
|
|
|
#include "debug_dvi.h" |
|
#include "fontMap.h" |
|
#include <QFile> |
|
#include <QLoggingCategory> |
|
#include <QProcess> |
|
#include <QStandardPaths> |
|
#include <QTextStream> |
|
|
|
//#define DEBUG_FONTMAP |
|
|
|
fontMap::fontMap() |
|
{ |
|
// Make sure kpsewhich is in PATH and not just in the CWD |
|
static const QString kpsewhichFullPath = QStandardPaths::findExecutable(QStringLiteral("kpsewhich")); |
|
|
|
// Read the map file of ps2pk which will provide us with a |
|
// dictionary "TeX Font names" <-> "Name of font files, Font Names |
|
// and Encodings" (example: the font "Times-Roman" is called |
|
// "ptmr8y" in the DVI file, but the Type1 font file name is |
|
// "utmr8a.pfb". We use the map file of "ps2pk" because that program |
|
// has, like kdvi (and unlike dvips), no built-in fonts. |
|
|
|
// Finding ps2pk.map is not easy. In teTeX < 3.0, the kpsewhich |
|
// program REQUIRES the option "--format=dvips config". In teTeX = |
|
// 3.0, the option "--format=map" MUST be used. Since there is no |
|
// way to give both options at the same time, there is seemingly no |
|
// other way than to try both options one after another. We use the |
|
// teTeX 3.0 format first. |
|
QProcess kpsewhich; |
|
kpsewhich.start(kpsewhichFullPath, QStringList() << QStringLiteral("--format=map") << QStringLiteral("ps2pk.map"), QIODevice::ReadOnly | QIODevice::Text); |
|
|
|
if (!kpsewhich.waitForStarted()) { |
|
qCCritical(OkularDviDebug) << "fontMap::fontMap(): kpsewhich could not be started." << endl; |
|
return; |
|
} |
|
|
|
// We wait here while the external program runs concurrently. |
|
kpsewhich.waitForFinished(-1); |
|
|
|
QString map_fileName = QString::fromLocal8Bit(kpsewhich.readAll()).trimmed(); |
|
if (map_fileName.isEmpty()) { |
|
// Map file not found? Then we try the teTeX < 3.0 way of finding |
|
// the file. |
|
kpsewhich.start(kpsewhichFullPath, QStringList() << QStringLiteral("--format=dvips config") << QStringLiteral("ps2pk.map"), QIODevice::ReadOnly | QIODevice::Text); |
|
if (!kpsewhich.waitForStarted()) { |
|
qCCritical(OkularDviDebug) << "fontMap::fontMap(): kpsewhich could not be started." << endl; |
|
return; |
|
} |
|
|
|
kpsewhich.waitForFinished(-1); |
|
|
|
map_fileName = QString::fromLocal8Bit(kpsewhich.readAll()).trimmed(); |
|
// If both versions fail, then there is nothing left to do. |
|
if (map_fileName.isEmpty()) { |
|
qCCritical(OkularDviDebug) << "fontMap::fontMap(): The file 'ps2pk.map' could not be found by kpsewhich." << endl; |
|
return; |
|
} |
|
} |
|
|
|
QFile file(map_fileName); |
|
if (file.open(QIODevice::ReadOnly)) { |
|
QTextStream stream(&file); |
|
QString line; |
|
while (!stream.atEnd()) { |
|
line = stream.readLine().simplified(); |
|
if (line.isEmpty() || (line.at(0) == QLatin1Char('%'))) |
|
continue; |
|
|
|
QString TeXName = line.section(QLatin1Char(' '), 0, 0); |
|
QString FullName = line.section(QLatin1Char(' '), 1, 1); |
|
QString fontFileName = line.section(QLatin1Char('<'), -1).trimmed().section(QLatin1Char(' '), 0, 0); |
|
QString encodingName = line.section(QLatin1Char('<'), -2, -2).trimmed().section(QLatin1Char(' '), 0, 0); |
|
// It seems that sometimes the encoding is prepended by the |
|
// letter '[', which we ignore |
|
if ((!encodingName.isEmpty()) && (encodingName[0] == QLatin1Char('['))) |
|
encodingName = encodingName.mid(1); |
|
|
|
double slant = 0.0; |
|
int i = line.indexOf(QStringLiteral("SlantFont")); |
|
if (i >= 0) { |
|
bool ok; |
|
slant = line.left(i).section(QLatin1Char(' '), -1, -1, QString::SectionSkipEmpty).toDouble(&ok); |
|
if (ok == false) |
|
slant = 0.0; |
|
} |
|
|
|
fontMapEntry &entry = fontMapEntries[TeXName]; |
|
|
|
entry.slant = slant; |
|
entry.fontFileName = fontFileName; |
|
entry.fullFontName = FullName; |
|
if (encodingName.endsWith(QLatin1String(".enc"))) |
|
entry.fontEncoding = encodingName; |
|
else |
|
entry.fontEncoding.clear(); |
|
} |
|
file.close(); |
|
} else |
|
qCCritical(OkularDviDebug) << QStringLiteral("fontMap::fontMap(): The file '%1' could not be opened.").arg(map_fileName) << endl; |
|
|
|
#ifdef DEBUG_FONTMAP |
|
qCDebug(OkularDviDebug) << "FontMap file parsed. Results:"; |
|
QMap<QString, fontMapEntry>::Iterator it; |
|
for (it = fontMapEntries.begin(); it != fontMapEntries.end(); ++it) |
|
qCDebug(OkularDviDebug) << "TeXName: " << it.key() << ", FontFileName=" << it.data().fontFileName << ", FullName=" << it.data().fullFontName << ", Encoding=" << it.data().fontEncoding << "." << endl; |
|
; |
|
#endif |
|
} |
|
|
|
const QString &fontMap::findFileName(const QString &TeXName) |
|
{ |
|
QMap<QString, fontMapEntry>::Iterator it = fontMapEntries.find(TeXName); |
|
|
|
if (it != fontMapEntries.end()) |
|
return it.value().fontFileName; |
|
|
|
static const QString nullstring; |
|
return nullstring; |
|
} |
|
|
|
const QString &fontMap::findFontName(const QString &TeXName) |
|
{ |
|
QMap<QString, fontMapEntry>::Iterator it = fontMapEntries.find(TeXName); |
|
|
|
if (it != fontMapEntries.end()) |
|
return it.value().fullFontName; |
|
|
|
static const QString nullstring; |
|
return nullstring; |
|
} |
|
|
|
const QString &fontMap::findEncoding(const QString &TeXName) |
|
{ |
|
QMap<QString, fontMapEntry>::Iterator it = fontMapEntries.find(TeXName); |
|
|
|
if (it != fontMapEntries.end()) |
|
return it.value().fontEncoding; |
|
|
|
static const QString nullstring; |
|
return nullstring; |
|
} |
|
|
|
double fontMap::findSlant(const QString &TeXName) |
|
{ |
|
QMap<QString, fontMapEntry>::Iterator it = fontMapEntries.find(TeXName); |
|
|
|
if (it != fontMapEntries.end()) |
|
return it.value().slant; |
|
else |
|
return 0.0; |
|
} |
|
|
|
#endif // HAVE_FREETYPE
|
|
|