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.
767 lines
24 KiB
767 lines
24 KiB
// fontpool.cpp |
|
// |
|
// (C) 2001-2003 Stefan Kebekus |
|
// Distributed under the GPL |
|
|
|
#include <kconfig.h> |
|
#include <kdebug.h> |
|
#include <kinstance.h> |
|
#include <klocale.h> |
|
#include <kmessagebox.h> |
|
#include <kprocess.h> |
|
#include <kprocio.h> |
|
#include <kstringhandler.h> |
|
|
|
#include <qapplication.h> |
|
#include <qfile.h> |
|
#include <qimage.h> |
|
#include <qpainter.h> |
|
#include <stdlib.h> |
|
|
|
#include "fontpool.h" |
|
#include "fontprogress.h" |
|
#include "performanceMeasurement.h" |
|
#include "TeXFont.h" |
|
|
|
|
|
|
|
|
|
|
|
// List of permissible MetaFontModes which are supported by kdvi. |
|
|
|
const char *MFModes[] = { "cx", "ljfour", "lexmarks" }; |
|
const char *MFModenames[] = { "Canon CX", "LaserJet 4", "Lexmark S" }; |
|
const int MFResolutions[] = { 300, 600, 1200 }; |
|
|
|
#ifdef PERFORMANCE_MEASUREMENT |
|
QTime fontPoolTimer; |
|
bool fontPoolTimerFlag; |
|
#endif |
|
|
|
//#define DEBUG_FONTPOOL |
|
|
|
fontPool::fontPool(void) |
|
{ |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "fontPool::fontPool(void) called" << endl; |
|
#endif |
|
|
|
setName("Font Pool"); |
|
|
|
proc = 0; |
|
makepk = true; // By default, fonts are generated |
|
displayResolution_in_dpi = 100.0; // A not-too-bad-default |
|
MetafontMode = DefaultMFMode; |
|
useType1Fonts = true; |
|
useFontHints = true; |
|
CMperDVIunit = 0; |
|
fontList.setAutoDelete(TRUE); |
|
|
|
|
|
|
|
#ifdef HAVE_FREETYPE |
|
// Initialize the Freetype Library |
|
if ( FT_Init_FreeType( &FreeType_library ) != 0 ) { |
|
kdError(4300) << "Cannot load the FreeType library. KDVI proceeds without FreeType support." << endl; |
|
FreeType_could_be_loaded = false; |
|
} else |
|
FreeType_could_be_loaded = true; |
|
#endif |
|
|
|
progress = new fontProgressDialog( "fontgen", // Chapter in the documentation for help. |
|
i18n( "KDVI is currently generating bitmap fonts..." ), |
|
i18n( "Aborts the font generation. Don't do this." ), |
|
i18n( "KDVI is currently generating bitmap fonts which are needed to display your document. " |
|
"For this, KDVI uses a number of external programs, such as MetaFont. You can find " |
|
"the output of these programs later in the document info dialog." ), |
|
i18n( "KDVI is generating fonts. Please wait." ), |
|
0 ); |
|
if (progress == NULL) |
|
kdError(4300) << "Could not allocate memory for the font progress dialog." << endl; |
|
else { |
|
qApp->connect(this, SIGNAL(hide_progress_dialog()), progress, SLOT(hideDialog())); |
|
qApp->connect(this, SIGNAL(totalFontsInJob(int)), progress, SLOT(setTotalSteps(int))); |
|
qApp->connect(this, SIGNAL(show_progress(void)), progress, SLOT(show(void))); |
|
qApp->connect(progress, SIGNAL(finished(void)), this, SLOT(abortGeneration(void))); |
|
} |
|
|
|
|
|
// Check if the QT library supports the alpha channel of |
|
// pixmaps. Experiments show that --depending of the configuration |
|
// of QT at compile and runtime or the availability of the XFt |
|
// extension, alpha channels are either supported, or silently |
|
// converted to 1-bit masks. |
|
QImage start(1, 1, 32); // Generate a 1x1 image, black with alpha=0x10 |
|
start.setAlphaBuffer(true); |
|
Q_UINT32 *destScanLine = (Q_UINT32 *)start.scanLine(0); |
|
*destScanLine = 0x80000000; |
|
QPixmap intermediate(start); |
|
QPixmap dest(1,1); |
|
dest.fill(Qt::white); |
|
QPainter paint( &dest ); |
|
paint.drawPixmap(0, 0, intermediate); |
|
paint.end(); |
|
start = dest.convertToImage().convertDepth(32); |
|
Q_UINT8 result = *(start.scanLine(0)) & 0xff; |
|
|
|
if ((result == 0xff) || (result == 0x00)) { |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "fontPool::fontPool(): QPixmap does not support the alpha channel" << endl; |
|
#endif |
|
QPixmapSupportsAlpha = false; |
|
} else { |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "fontPool::fontPool(): QPixmap supports the alpha channel" << endl; |
|
#endif |
|
QPixmapSupportsAlpha = true; |
|
} |
|
} |
|
|
|
|
|
fontPool::~fontPool(void) |
|
{ |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "fontPool::~fontPool(void) called" << endl; |
|
#endif |
|
|
|
#ifdef HAVE_FREETYPE |
|
if (FreeType_could_be_loaded == true) |
|
FT_Done_FreeType( FreeType_library ); |
|
#endif |
|
delete proc; |
|
delete progress; |
|
} |
|
|
|
|
|
void fontPool::setParameters( unsigned int _metafontMode, bool _makePK, bool _useType1Fonts, bool _useFontHints ) |
|
{ |
|
if (_metafontMode >= NumberOfMFModes) { |
|
kdError(4300) << "fontPool::setMetafontMode called with argument " << _metafontMode |
|
<< " which is more than the allowed value of " << NumberOfMFModes-1 << endl; |
|
kdError(4300) << "setting mode to " << MFModes[DefaultMFMode] << " at " |
|
<< MFResolutions[DefaultMFMode] << "dpi" << endl; |
|
_metafontMode = DefaultMFMode; |
|
} |
|
|
|
bool kpsewhichNeeded = false; |
|
|
|
// Check if a new run of kpsewhich is required |
|
if ( (_metafontMode != MetafontMode) || (_useType1Fonts != useType1Fonts) ) { |
|
TeXFontDefinition *fontp = fontList.first(); |
|
while(fontp != 0 ) { |
|
fontp->reset(); |
|
fontp = fontList.next(); |
|
} |
|
kpsewhichNeeded = true; |
|
} |
|
|
|
// If we enable font generation, we look for fonts which have not |
|
// yet been loaded, mark them as "not yet looked up" and try to run |
|
// kpsewhich once more. |
|
if ((_makePK == true) && (_makePK != makepk)) { |
|
TeXFontDefinition *fontp =fontList.first(); |
|
while(fontp != 0 ) { |
|
if (fontp->filename.isEmpty() ) |
|
fontp->flags &= ~TeXFontDefinition::FONT_KPSE_NAME; |
|
fontp=fontList.next(); |
|
} |
|
kpsewhichNeeded = true; |
|
} |
|
|
|
// Check if glyphs need to be cleared |
|
if (_useFontHints != useFontHints) { |
|
double displayResolution = displayResolution_in_dpi; |
|
TeXFontDefinition *fontp = fontList.first(); |
|
while(fontp != 0 ) { |
|
fontp->setDisplayResolution(displayResolution * fontp->enlargement); |
|
fontp=fontList.next(); |
|
} |
|
} |
|
|
|
MetafontMode = _metafontMode; |
|
makepk = _makePK; |
|
useType1Fonts = _useType1Fonts; |
|
useFontHints = _useFontHints; |
|
|
|
// Initiate a new concurrently running process of kpsewhich, if |
|
// necessary. Otherwise, let the dvi window be redrawn |
|
if (kpsewhichNeeded == true) |
|
check_if_fonts_filenames_are_looked_up(); |
|
else |
|
emit fonts_have_been_loaded(this); |
|
} |
|
|
|
|
|
class TeXFontDefinition *fontPool::appendx(QString fontname, Q_UINT32 checksum, Q_UINT32 scale, double enlargement) |
|
{ |
|
// Reuse font if possible: check if a font with that name and |
|
// natural resolution is already in the fontpool, and use that, if |
|
// possible. |
|
TeXFontDefinition *fontp = fontList.first(); |
|
while( fontp != 0 ) { |
|
if ((fontname == fontp->fontname) && ( (int)(enlargement*1000.0+0.5)) == (int)(fontp->enlargement*1000.0+0.5)) { |
|
// if font is already in the list |
|
fontp->mark_as_used(); |
|
return fontp; |
|
} |
|
fontp=fontList.next(); |
|
} |
|
|
|
// If font doesn't exist yet, we have to generate a new font. |
|
|
|
double displayResolution = displayResolution_in_dpi; |
|
|
|
fontp = new TeXFontDefinition(fontname, displayResolution*enlargement, checksum, scale, this, enlargement); |
|
if (fontp == 0) { |
|
kdError(4300) << i18n("Could not allocate memory for a font structure!") << endl; |
|
exit(0); |
|
} |
|
fontList.append(fontp); |
|
|
|
#ifdef PERFORMANCE_MEASUREMENT |
|
fontPoolTimer.start(); |
|
fontPoolTimerFlag = false; |
|
#endif |
|
|
|
// Now start kpsewhich/MetaFont, etc. if necessary |
|
return fontp; |
|
} |
|
|
|
|
|
QString fontPool::status(void) |
|
{ |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "fontPool::status() called" << endl; |
|
#endif |
|
|
|
QString text; |
|
QStringList tmp; |
|
|
|
if (fontList.isEmpty()) |
|
return i18n("The fontlist is currently empty."); |
|
|
|
text.append("<table WIDTH=\"100%\" NOSAVE >"); |
|
text.append( QString("<tr><td><b>%1</b></td> <td><b>%2</b></td> <td><b>%3</b></td> <td><b>%4</b> <td><b>%5</b></td> <td><b>%6</b></td></tr>") |
|
.arg(i18n("TeX Name")) |
|
.arg(i18n("Family")) |
|
.arg(i18n("Zoom")) |
|
.arg(i18n("Type")) |
|
.arg(i18n("Encoding")) |
|
.arg(i18n("Comment")) ); |
|
|
|
TeXFontDefinition *fontp = fontList.first(); |
|
while ( fontp != 0 ) { |
|
QString errMsg, encoding; |
|
|
|
if (!(fontp->flags & TeXFontDefinition::FONT_VIRTUAL)) { |
|
#ifdef HAVE_FREETYPE |
|
encoding = fontp->getFullEncodingName(); |
|
#endif |
|
if (fontp->font != 0) |
|
errMsg = fontp->font->errorMessage; |
|
else |
|
errMsg = i18n("Font file not found"); |
|
} |
|
|
|
#ifdef HAVE_FREETYPE |
|
tmp << QString ("<tr><td>%1</td> <td>%2</td> <td>%3%</td> <td>%4</td> <td>%5</td> <td>%6</td></tr>") |
|
.arg(fontp->fontname) |
|
.arg(fontp->getFullFontName()) |
|
.arg((int)(fontp->enlargement*100 + 0.5)) |
|
.arg(fontp->getFontTypeName()) |
|
.arg(encoding) |
|
.arg(errMsg); |
|
#endif |
|
|
|
fontp=fontList.next(); |
|
} |
|
|
|
tmp.sort(); |
|
text.append(tmp.join("\n")); |
|
text.append("</table>"); |
|
|
|
return text; |
|
} |
|
|
|
|
|
bool fontPool::check_if_fonts_filenames_are_looked_up(void) |
|
{ |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "fontPool::check_if_fonts_filenames_are_looked_up(void) called" << endl; |
|
#endif |
|
|
|
// Check if kpsewhich is still running. In that case certainly not |
|
// all fonts have been properly looked up. |
|
if (proc != 0) { |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "... no, kpsewhich is still running." << endl; |
|
#endif |
|
return false; |
|
} |
|
|
|
// Is there a font whose name we did not try to find out yet? |
|
TeXFontDefinition *fontp = fontList.first(); |
|
while( fontp != 0 ) { |
|
if ((fontp->flags & TeXFontDefinition::FONT_KPSE_NAME) == 0) |
|
break; |
|
fontp=fontList.next(); |
|
} |
|
|
|
if (fontp == 0) { |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "... yes, all fonts are there, or could not be found." << endl; |
|
#endif |
|
return true; // That says that all fonts are loaded. |
|
} |
|
|
|
pass = 0; |
|
start_kpsewhich(); |
|
return false; // That says that not all fonts are loaded. |
|
} |
|
|
|
|
|
void fontPool::start_kpsewhich(void) |
|
{ |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "fontPool::start_kpsewhich(void) called" << endl; |
|
#endif |
|
|
|
// Check if kpsewhich is still running. In that case we certainly do |
|
// not want to run another kpsewhich process |
|
if (proc != 0) { |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "kpsewhich is still running." << endl; |
|
#endif |
|
return; |
|
} |
|
|
|
// Just make sure that MetafontMode is in the permissible range, so |
|
// as to avoid segfaults. |
|
if (MetafontMode >= NumberOfMFModes) { |
|
kdError(4300) << "fontPool::appendx called with bad MetafontMode " << MetafontMode |
|
<< " which is more than the allowed value of " << NumberOfMFModes-1 << endl |
|
<< "setting mode to " << MFModes[DefaultMFMode] << " at " |
|
<< MFResolutions[DefaultMFMode] << "dpi" << endl; |
|
MetafontMode = DefaultMFMode; |
|
} |
|
|
|
// Set up the kpsewhich process. If pass == 0, look for vf-fonts and |
|
// disable automatic font generation as vf-fonts can't be |
|
// generated. If pass == 0, ennable font generation, if it was |
|
// enabled globally. |
|
emit setStatusBarText(i18n("Locating fonts...")); |
|
|
|
#ifdef DEBUG_FONTPOOL |
|
QString shellProcessCmdLine; |
|
#endif |
|
|
|
proc = new KShellProcess(); |
|
if (proc == 0) { |
|
kdError(4300) << "Could not allocate ShellProcess for the kpsewhich command." << endl; |
|
exit(0); |
|
} |
|
MetafontOutput.left(0); |
|
qApp->connect(proc, SIGNAL(receivedStdout(KProcess *, char *, int)), |
|
this, SLOT(kpsewhich_output_receiver(KProcess *, char *, int))); |
|
qApp->connect(proc, SIGNAL(processExited(KProcess *)), |
|
this, SLOT(kpsewhich_terminated(KProcess *))); |
|
qApp->connect(proc, SIGNAL(receivedStderr(KProcess *, char *, int)), |
|
this, SLOT(mf_output_receiver(KProcess *, char *, int))); |
|
emit(new_kpsewhich_run(i18n("Font Generation"))); |
|
|
|
proc->clearArguments(); |
|
*proc << "kpsewhich"; |
|
#ifdef DEBUG_FONTPOOL |
|
shellProcessCmdLine += "kpsewhich "; |
|
#endif |
|
*proc << QString("--dpi %1").arg(MFResolutions[MetafontMode]); |
|
#ifdef DEBUG_FONTPOOL |
|
shellProcessCmdLine += QString("--dpi %1").arg(MFResolutions[MetafontMode]) + " "; |
|
#endif |
|
*proc << QString("--mode %1").arg(KShellProcess::quote(MFModes[MetafontMode])); |
|
#ifdef DEBUG_FONTPOOL |
|
shellProcessCmdLine += QString("--mode %1").arg(KShellProcess::quote(MFModes[MetafontMode])) + " "; |
|
#endif |
|
|
|
// Enable automatic pk-font generation only in the second pass. (If |
|
// automatic font generation is switched off, this method will never |
|
// be called with pass==1) |
|
if (pass == 1) { |
|
*proc << "--mktex pk"; |
|
#ifdef DEBUG_FONTPOOL |
|
shellProcessCmdLine += "--mktex pk "; |
|
#endif |
|
} else { |
|
*proc << "--no-mktex pk"; |
|
#ifdef DEBUG_FONTPOOL |
|
shellProcessCmdLine += "--no-mktex pk "; |
|
#endif |
|
} |
|
|
|
int numFontsInJob = 0; |
|
|
|
TeXFontDefinition *fontp = fontList.first(); |
|
while ( fontp != 0 ) { |
|
if ((fontp->flags & TeXFontDefinition::FONT_KPSE_NAME) == 0) { |
|
numFontsInJob++; |
|
|
|
switch(pass){ |
|
case 0: |
|
// In the first pass, we look for PK fonts, and also for virtual fonts. |
|
#ifdef HAVE_FREETYPE |
|
if ((useType1Fonts == true) && (FreeType_could_be_loaded == true)) { |
|
const QString &filename = fontsByTeXName.findFileName(fontp->fontname); |
|
*proc << KShellProcess::quote(QString("%1").arg(filename)); |
|
#ifdef DEBUG_FONTPOOL |
|
shellProcessCmdLine += KShellProcess::quote(QString("%1").arg(filename)) + " "; |
|
#endif |
|
} |
|
#endif |
|
*proc << KShellProcess::quote(QString("%1.vf").arg(fontp->fontname)); |
|
*proc << KShellProcess::quote(QString("%2.%1pk").arg(MFResolutions[MetafontMode]).arg(fontp->fontname)); |
|
#ifdef DEBUG_FONTPOOL |
|
shellProcessCmdLine += KShellProcess::quote(QString("%1.vf").arg(fontp->fontname)) + " "; |
|
shellProcessCmdLine += KShellProcess::quote(QString("%2.%1pk").arg(MFResolutions[MetafontMode]).arg(fontp->fontname)) + " "; |
|
#endif |
|
break; |
|
case 1: |
|
// In the second pass, we generate PK fonts, but we also look |
|
// for PFB fonts, as they might be used by virtual fonts. |
|
#ifdef HAVE_FREETYPE |
|
if ((useType1Fonts == true) && (FreeType_could_be_loaded == true)) { |
|
const QString &filename = fontsByTeXName.findFileName(fontp->fontname); |
|
*proc << KShellProcess::quote(QString("%1").arg(filename)); |
|
#ifdef DEBUG_FONTPOOL |
|
shellProcessCmdLine += KShellProcess::quote(QString("%1").arg(filename)) + " "; |
|
#endif |
|
} |
|
#endif |
|
*proc << KShellProcess::quote(QString("%2.%1pk").arg(MFResolutions[MetafontMode]).arg(fontp->fontname)); |
|
#ifdef DEBUG_FONTPOOL |
|
shellProcessCmdLine += KShellProcess::quote(QString("%2.%1pk").arg(MFResolutions[MetafontMode]).arg(fontp->fontname)) + " "; |
|
#endif |
|
break; |
|
default: |
|
// In the third pass, as a last resort, try to find TFM files |
|
*proc << KShellProcess::quote(QString("%1.tfm").arg(fontp->fontname)); |
|
#ifdef DEBUG_FONTPOOL |
|
shellProcessCmdLine += KShellProcess::quote(QString("%1.tfm").arg(fontp->fontname)) + " "; |
|
#endif |
|
break; |
|
} |
|
|
|
// In the second (last) pass, mark the font "looked up". As this |
|
// is the last chance that the filename could be found, we |
|
// ensure that if the filename is still not found now, we won't |
|
// look any further. |
|
if (pass == 2) |
|
fontp->flags |= TeXFontDefinition::FONT_KPSE_NAME; |
|
} |
|
fontp=fontList.next(); |
|
} |
|
|
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "pass " << pass << " kpsewhich run with " << numFontsInJob << "fonts to locate." << endl; |
|
kdDebug(4300) << "command line: " << shellProcessCmdLine << endl; |
|
#endif |
|
|
|
if (pass != 0) |
|
emit(totalFontsInJob(numFontsInJob)); |
|
|
|
kpsewhichOutput = ""; |
|
MetafontOutput = ""; |
|
proc->closeStdin(); |
|
if (proc->start(KProcess::NotifyOnExit, KProcess::AllOutput) == false) { |
|
kdError(4300) << "kpsewhich failed to start" << endl; |
|
} |
|
} |
|
|
|
|
|
void fontPool::kpsewhich_terminated(KProcess *) |
|
{ |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "kpsewhich terminated. Output was " << endl << kpsewhichOutput << endl; |
|
#endif |
|
|
|
emit(hide_progress_dialog()); |
|
|
|
// Handle fatal errors. The content of fatal_error_in_kpsewhich will |
|
// later be used to generate the proper text for error messages. |
|
bool fatal_error_in_kpsewhich = false; |
|
if (proc->normalExit()) |
|
if (proc->exitStatus() == 127) |
|
fatal_error_in_kpsewhich = true; |
|
if (fatal_error_in_kpsewhich) { |
|
// Mark all fonts as done so kpsewhich will not be called again |
|
// soon. |
|
TeXFontDefinition *fontp=fontList.first(); |
|
while ( fontp != 0 ) { |
|
fontp->flags |= TeXFontDefinition::FONT_KPSE_NAME; |
|
fontp = fontList.next(); |
|
} |
|
} |
|
|
|
delete proc; |
|
proc = 0; |
|
|
|
QStringList fileNameList = QStringList::split('\n', kpsewhichOutput); |
|
|
|
TeXFontDefinition *fontp=fontList.first(); |
|
while ( fontp != 0 ) { |
|
if (fontp->filename.isEmpty() == true) { |
|
QStringList matchingFiles; |
|
#ifdef HAVE_FREETYPE |
|
const QString &fn = fontsByTeXName.findFileName(fontp->fontname); |
|
if (!fn.isEmpty()) |
|
matchingFiles = fileNameList.grep(fn); |
|
#endif |
|
if (matchingFiles.isEmpty() == true) |
|
matchingFiles += fileNameList.grep(fontp->fontname); |
|
|
|
if (matchingFiles.isEmpty() != true) { |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "Associated " << fontp->fontname << " to " << matchingFiles.first() << endl; |
|
#endif |
|
fontp->fontNameReceiver(matchingFiles.first()); |
|
fontp->flags |= TeXFontDefinition::FONT_KPSE_NAME; |
|
// Constructing a virtual font will most likely insert other |
|
// fonts into the fontList. After that, fontList.next() will |
|
// no longer work. It is therefore safer to start over. |
|
fontp=fontList.first(); |
|
continue; |
|
} |
|
} // of if (fontp->filename.isEmpty() == true) |
|
fontp = fontList.next(); |
|
} |
|
|
|
// Check if some font filenames are still missing. If not, or if we |
|
// have just finished the last pass, we quit here. |
|
bool all_fonts_are_found = true; |
|
|
|
fontp = fontList.first(); |
|
while ( fontp != 0 ) { |
|
if (fontp->filename.isEmpty() == true) { |
|
all_fonts_are_found = false; |
|
break; |
|
} |
|
fontp=fontList.next(); |
|
} |
|
if ((all_fonts_are_found) || (pass >= 2)) { |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "Emitting fonts_have_been_loaded(this)" << endl; |
|
#endif |
|
#ifdef PERFORMANCE_MEASUREMENT |
|
kdDebug(4300) << "Time required to look up fonts: " << fontPoolTimer.elapsed() << "ms" << endl; |
|
#endif |
|
emit setStatusBarText(QString::null); |
|
emit fonts_have_been_loaded(this); |
|
return; |
|
} |
|
|
|
if (pass == 0) { |
|
pass = 1; |
|
// If automatic pk-font generation is enabled, we call |
|
// check_if_fonts_filenames_are_looked_up. |
|
if (makepk != 0) { |
|
start_kpsewhich(); |
|
return; |
|
} |
|
} |
|
|
|
if (pass == 1) { |
|
// Now all fonts should be there. It may, however, have happened |
|
// that still not all fonts were found. If that is so, issue a |
|
// warning here. |
|
bool all_fonts_are_found = true; |
|
|
|
fontp = fontList.first(); |
|
while ( fontp != 0 ) { |
|
if (fontp->filename.isEmpty() == true) { |
|
|
|
all_fonts_are_found = false; |
|
break; |
|
} |
|
fontp=fontList.next(); |
|
} |
|
|
|
if (all_fonts_are_found == false) { |
|
QString title = i18n("Font not found - KDVI"); |
|
QString nokps = i18n("There were problems running the kpsewhich program. " |
|
"KDVI will not work if TeX is not installed on your " |
|
"system or if the kpsewhich program cannot be found " |
|
"in the standard search path.\n"); |
|
QString body = i18n("KDVI was not able to locate all the font files " |
|
"which are necessary to display the current DVI file. " |
|
"Your document might be unreadable."); |
|
QString metaf = i18n("\nExperts will find helpful information in the 'Fonts'-" |
|
"section of the document info dialog"); |
|
|
|
if (fatal_error_in_kpsewhich == true) |
|
KMessageBox::sorry( 0, nokps+body+metaf, title ); |
|
else |
|
if (makepk == 0) { |
|
if(KMessageBox::warningYesNo( 0, body+i18n("\nAutomatic font generation is switched off. " |
|
"You might want to switch it on now and generate the missing fonts."), title, |
|
i18n("Generate Fonts Now"), i18n("Continue Without"), "WarnForMissingFonts" ) == KMessageBox::Yes) { |
|
KInstance *instance = new KInstance("kdvi"); |
|
KConfig *config = instance->config(); |
|
config->setGroup("kdvi"); |
|
config->writeEntry( "MakePK", true ); |
|
config->sync(); |
|
setParameters( MetafontMode, true, useType1Fonts, useFontHints ); // That will start kpsewhich again. |
|
return; |
|
} |
|
} else |
|
KMessageBox::sorry( 0, body+metaf, title ); |
|
} |
|
|
|
pass = 2; |
|
start_kpsewhich(); |
|
return; |
|
} |
|
} |
|
|
|
|
|
void fontPool::setCMperDVIunit( double _CMperDVI ) |
|
{ |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "fontPool::setCMperDVIunit( " << _CMperDVI << " )" << endl; |
|
#endif |
|
|
|
if (CMperDVIunit == _CMperDVI) |
|
return; |
|
|
|
CMperDVIunit = _CMperDVI; |
|
|
|
TeXFontDefinition *fontp = fontList.first(); |
|
while(fontp != 0 ) { |
|
fontp->setDisplayResolution(displayResolution_in_dpi * fontp->enlargement); |
|
fontp=fontList.next(); |
|
} |
|
} |
|
|
|
|
|
void fontPool::setDisplayResolution( double _displayResolution_in_dpi ) |
|
{ |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "fontPool::setDisplayResolution( displayResolution_in_dpi=" << _displayResolution_in_dpi << " ) called" << endl; |
|
#endif |
|
displayResolution_in_dpi = _displayResolution_in_dpi; |
|
double displayResolution = displayResolution_in_dpi; |
|
|
|
TeXFontDefinition *fontp = fontList.first(); |
|
while(fontp != 0 ) { |
|
fontp->setDisplayResolution(displayResolution * fontp->enlargement); |
|
fontp=fontList.next(); |
|
} |
|
|
|
// Do something that causes re-rendering of the dvi-window |
|
emit fonts_have_been_loaded(this); |
|
} |
|
|
|
|
|
void fontPool::mark_fonts_as_unused(void) |
|
{ |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "fontPool::mark_fonts_as_unused(void) called" << endl; |
|
#endif |
|
|
|
TeXFontDefinition *fontp = fontList.first(); |
|
while ( fontp != 0 ) { |
|
fontp->flags &= ~TeXFontDefinition::FONT_IN_USE; |
|
fontp=fontList.next(); |
|
} |
|
} |
|
|
|
|
|
void fontPool::release_fonts(void) |
|
{ |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "Release_fonts" << endl; |
|
#endif |
|
|
|
TeXFontDefinition *fontp = fontList.first(); |
|
while(fontp != 0) { |
|
if ((fontp->flags & TeXFontDefinition::FONT_IN_USE) != TeXFontDefinition::FONT_IN_USE) { |
|
fontList.removeRef(fontp); |
|
fontp = fontList.first(); |
|
} else |
|
fontp = fontList.next(); |
|
} |
|
} |
|
|
|
|
|
void fontPool::mf_output_receiver(KProcess *, char *buffer, int buflen) |
|
{ |
|
// Paranoia. |
|
if (buflen < 0) |
|
return; |
|
|
|
QString op = QString::fromLocal8Bit(buffer, buflen); |
|
|
|
MetafontOutput.append(op); |
|
|
|
// We'd like to print only full lines of text. |
|
int numleft; |
|
bool show_prog = false; |
|
while( (numleft = MetafontOutput.find('\n')) != -1) { |
|
QString line = MetafontOutput.left(numleft+1); |
|
emit(MFOutput(line)); |
|
#ifdef DEBUG_FONTPOOL |
|
kdDebug(4300) << "MF OUTPUT RECEIVED: " << line; |
|
#endif |
|
// Search for a line which marks the beginning of a MetaFont run |
|
// and show the progress dialog at the end of this method. |
|
if (line.find("kpathsea:") == 0) |
|
show_prog = true; |
|
|
|
// If the Output of the kpsewhich program contains a line starting |
|
// with "kpathsea:", this means that a new MetaFont-run has been |
|
// started. We filter these lines out and update the display |
|
// accordingly. |
|
int startlineindex = line.find("kpathsea:"); |
|
if (startlineindex != -1) { |
|
int endstartline = line.find("\n",startlineindex); |
|
QString startLine = line.mid(startlineindex,endstartline-startlineindex); |
|
|
|
// The last word in the startline is the name of the font which we |
|
// are generating. The second-to-last word is the resolution in |
|
// dots per inch. Display this info in the text label below the |
|
// progress bar. |
|
int lastblank = startLine.findRev(' '); |
|
QString fontName = startLine.mid(lastblank+1); |
|
int secondblank = startLine.findRev(' ',lastblank-1); |
|
QString dpi = startLine.mid(secondblank+1,lastblank-secondblank-1); |
|
|
|
progress->increaseNumSteps( i18n("Currently generating %1 at %2 dpi").arg(fontName).arg(dpi) ); |
|
} |
|
|
|
MetafontOutput = MetafontOutput.remove(0,numleft+1); |
|
} |
|
|
|
// It is very important that this signal is emitted at the very end |
|
// of the method. The info-dialog is modal and QT branches into a |
|
// new event loop. The emit-command will therefore NOT return before |
|
// the dialog is closed, and the strings will be screwed up. |
|
if (show_prog == true) |
|
emit(show_progress()); |
|
} |
|
|
|
|
|
void fontPool::kpsewhich_output_receiver(KProcess *, char *buffer, int buflen) |
|
{ |
|
kpsewhichOutput.append(QString::fromLocal8Bit(buffer, buflen)); |
|
emit(numFoundFonts(kpsewhichOutput.contains('\n'))); |
|
} |
|
|
|
|
|
void fontPool::abortGeneration(void) |
|
{ |
|
kdDebug(4300) << "Font generation is aborted." << endl; |
|
if (proc != 0) |
|
if (proc->isRunning()) { |
|
proc->kill(); |
|
} |
|
} |
|
|
|
#include "fontpool.moc"
|
|
|