2000-05-26 00:00:15 +00:00
|
|
|
|
2000-07-08 11:10:43 +00:00
|
|
|
//#define DEBUG 0
|
2000-05-26 00:00:15 +00:00
|
|
|
|
2000-07-08 11:10:43 +00:00
|
|
|
#include <klocale.h>
|
2000-05-26 00:00:15 +00:00
|
|
|
#include <malloc.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
|
|
#include "font.h"
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
#include <kpathsea/config.h>
|
|
|
|
#include <kpathsea/c-fopen.h>
|
|
|
|
#include <kpathsea/c-stat.h>
|
|
|
|
#include <kpathsea/magstep.h>
|
|
|
|
#include <kpathsea/tex-glyph.h>
|
|
|
|
#include "dvi.h"
|
|
|
|
}
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "oconfig.h"
|
|
|
|
|
2000-05-27 05:05:03 +00:00
|
|
|
extern FILE *xfopen(const char *filename, const char *type);
|
2000-06-14 04:15:22 +00:00
|
|
|
extern void oops(QString message);
|
2000-05-26 00:00:15 +00:00
|
|
|
|
|
|
|
/** We try for a VF first because that's what dvips does. Also, it's
|
|
|
|
* easier to avoid running MakeTeXPK if we have a VF this way. */
|
|
|
|
|
2000-05-27 05:05:03 +00:00
|
|
|
FILE *font::font_open (char *font, char **font_ret, double dpi, int *dpi_ret, char **filename_ret)
|
2000-05-26 00:00:15 +00:00
|
|
|
{
|
|
|
|
FILE *ret;
|
|
|
|
char *name = kpse_find_vf (font);
|
|
|
|
|
|
|
|
if (name) {
|
|
|
|
// VF fonts don't have a resolution, but loadfont will complain if
|
|
|
|
// we don't return what it asked for.
|
|
|
|
*dpi_ret = (int)dpi;
|
|
|
|
*font_ret = NULL;
|
|
|
|
} else {
|
|
|
|
kpse_glyph_file_type file_ret;
|
|
|
|
name = kpse_find_glyph (font, (unsigned) (dpi + .5), kpse_any_glyph_format, &file_ret);
|
|
|
|
if (name) {
|
|
|
|
// If we got it normally, from an alias, or from MakeTeXPK,
|
|
|
|
// don't fill in FONT_RET. That tells load_font to complain.
|
|
|
|
|
|
|
|
// tell load_font we found something good
|
|
|
|
*font_ret = file_ret.source == kpse_glyph_source_fallback ? file_ret.name : NULL;
|
|
|
|
*dpi_ret = file_ret.dpi;
|
|
|
|
}
|
|
|
|
// If no VF and no PK, FONT_RET is irrelevant?
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we found a name, return the stream.
|
2000-05-27 05:05:03 +00:00
|
|
|
ret = name ? xfopen(name, FOPEN_R_MODE) : NULL;
|
2000-05-26 00:00:15 +00:00
|
|
|
*filename_ret = name;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern int n_files_left;
|
|
|
|
|
|
|
|
font::font(char *nfontname, float nfsize, long chk, int mag, double dconv)
|
|
|
|
{
|
2000-06-09 05:31:11 +00:00
|
|
|
#ifdef DEBUG_FONT
|
2000-06-05 10:49:44 +00:00
|
|
|
kdDebug() << "constructing font " << nfontname << " at " << (int) (nfsize + 0.5) << " dpi" << endl;
|
2000-06-09 05:31:11 +00:00
|
|
|
#endif
|
2000-05-26 00:00:15 +00:00
|
|
|
|
|
|
|
fontname = nfontname;
|
|
|
|
fsize = nfsize;
|
|
|
|
checksum = chk;
|
|
|
|
magstepval = mag;
|
2000-05-27 05:05:03 +00:00
|
|
|
flags = font::FONT_IN_USE;
|
2000-05-26 00:00:15 +00:00
|
|
|
file = NULL;
|
|
|
|
filename = NULL;
|
|
|
|
dimconv = dconv;
|
|
|
|
}
|
|
|
|
|
|
|
|
font::~font()
|
|
|
|
{
|
2000-06-09 05:31:11 +00:00
|
|
|
#ifdef DEBUG_FONT
|
2000-06-05 10:49:44 +00:00
|
|
|
kdDebug() << "discarding font " << fontname << " at " << (int)(fsize + 0.5) << " dpi" << endl;
|
2000-06-09 05:31:11 +00:00
|
|
|
#endif
|
2000-05-26 00:00:15 +00:00
|
|
|
|
|
|
|
free(fontname);
|
|
|
|
|
|
|
|
if (flags & FONT_LOADED) {
|
|
|
|
if (file != NULL) {
|
|
|
|
fclose(file);
|
|
|
|
++n_files_left;
|
|
|
|
}
|
|
|
|
free(filename);
|
|
|
|
|
|
|
|
if (flags & FONT_VIRTUAL) {
|
2000-05-27 05:05:03 +00:00
|
|
|
for (macro *m = macrotable; m < macrotable + max_num_of_chars_in_font; ++m)
|
2000-05-26 00:00:15 +00:00
|
|
|
if (m->free_me)
|
|
|
|
free((char *) m->pos);
|
2000-05-27 05:05:03 +00:00
|
|
|
free((char *) macrotable);
|
2000-05-26 00:00:15 +00:00
|
|
|
vf_table.clear();
|
|
|
|
} else {
|
2000-05-27 05:05:03 +00:00
|
|
|
for (glyph *g = glyphtable; g < glyphtable + max_num_of_chars_in_font; ++g)
|
2000-05-26 00:00:15 +00:00
|
|
|
delete g;
|
2000-05-27 05:05:03 +00:00
|
|
|
free((char *) glyphtable);
|
2000-05-26 00:00:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define PK_PRE 247
|
|
|
|
#define PK_ID 89
|
|
|
|
#define PK_MAGIC (PK_PRE << 8) + PK_ID
|
|
|
|
#define GF_PRE 247
|
|
|
|
#define GF_ID 131
|
|
|
|
#define GF_MAGIC (GF_PRE << 8) + GF_ID
|
|
|
|
#define VF_PRE 247
|
|
|
|
#define VF_ID_BYTE 202
|
|
|
|
#define VF_MAGIC (VF_PRE << 8) + VF_ID_BYTE
|
|
|
|
|
|
|
|
/** load_font locates the raster file and reads the index of
|
2000-05-27 05:05:03 +00:00
|
|
|
characters, plus whatever other preprocessing is done (depending
|
|
|
|
on the format). */
|
2000-05-26 00:00:15 +00:00
|
|
|
|
|
|
|
unsigned char font::load_font(void)
|
|
|
|
{
|
2000-06-09 05:31:11 +00:00
|
|
|
#ifdef DEBUG_FONT
|
2000-06-05 10:49:44 +00:00
|
|
|
kdDebug() << "loading font " << fontname << " at " << (int) (fsize + 0.5) << " dpi" << endl;
|
2000-06-09 05:31:11 +00:00
|
|
|
#endif
|
2000-05-26 00:00:15 +00:00
|
|
|
|
|
|
|
int dpi = (int)(fsize + 0.5);
|
|
|
|
char *font_found;
|
|
|
|
int size_found;
|
|
|
|
int magic;
|
|
|
|
|
2000-05-27 05:05:03 +00:00
|
|
|
flags |= font::FONT_LOADED;
|
|
|
|
file = font_open(fontname, &font_found, (double)fsize, &size_found, &filename);
|
2000-05-26 00:00:15 +00:00
|
|
|
if (file == NULL) {
|
2000-07-08 11:10:43 +00:00
|
|
|
kdError() << i18n("Can't find font ") << fontname << "." << endl;
|
2000-05-26 00:00:15 +00:00
|
|
|
return True;
|
|
|
|
}
|
|
|
|
--n_files_left;
|
|
|
|
if (font_found != NULL) {
|
2000-07-08 11:10:43 +00:00
|
|
|
kdError() << QString(i18n("Can't find font %1; using %2 instead at %3 dpi.")).arg(fontname).arg(font_found).arg(dpi) << endl;
|
2000-05-26 00:00:15 +00:00
|
|
|
free(fontname);
|
|
|
|
fontname = font_found;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (!kpse_bitmap_tolerance ((double) size_found, fsize))
|
2000-10-06 13:00:14 +00:00
|
|
|
kdError() << i18n("Can't find font %1 at %2 dpi; using %3 dpi instead.\n").arg(fontname).arg(dpi).arg(size_found);
|
2000-05-26 00:00:15 +00:00
|
|
|
fsize = size_found;
|
|
|
|
timestamp = ++current_timestamp;
|
2000-06-09 05:31:11 +00:00
|
|
|
set_char_p = &dviWindow::set_char;
|
2000-05-26 00:00:15 +00:00
|
|
|
magic = two(file);
|
|
|
|
|
|
|
|
if (magic == PK_MAGIC)
|
2000-06-07 01:41:55 +00:00
|
|
|
read_PK_index();
|
2000-05-26 00:00:15 +00:00
|
|
|
else
|
|
|
|
if (magic == GF_MAGIC)
|
2000-07-08 11:10:43 +00:00
|
|
|
oops(QString(i18n("The GF format for font file %1 is no longer supported")).arg(filename) );
|
2000-05-26 00:00:15 +00:00
|
|
|
else
|
|
|
|
if (magic == VF_MAGIC)
|
2000-06-07 01:41:55 +00:00
|
|
|
read_VF_index();
|
2000-05-26 00:00:15 +00:00
|
|
|
else
|
2000-07-08 11:10:43 +00:00
|
|
|
oops(QString(i18n("Cannot recognize format for font file %1")).arg(filename) );
|
2000-05-26 00:00:15 +00:00
|
|
|
|
|
|
|
return False;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** mark_as_used marks the font, and all the fonts it referrs to, as
|
2000-05-27 05:05:03 +00:00
|
|
|
used, i.e. their FONT_IN_USE-flag is set. */
|
2000-05-26 00:00:15 +00:00
|
|
|
|
|
|
|
void font::mark_as_used(void)
|
|
|
|
{
|
2000-06-09 05:31:11 +00:00
|
|
|
#ifdef DEBUG_FONT
|
|
|
|
kdDebug() << "marking font " << fontname << " at " << (int) (fsize + 0.5) << " dpi" << endl;
|
|
|
|
#endif
|
|
|
|
|
2000-05-27 05:05:03 +00:00
|
|
|
if (flags & font::FONT_IN_USE)
|
2000-05-26 00:00:15 +00:00
|
|
|
return;
|
|
|
|
|
2000-05-27 05:05:03 +00:00
|
|
|
flags |= font::FONT_IN_USE;
|
2000-05-26 00:00:15 +00:00
|
|
|
|
|
|
|
// For virtual fonts, also go through the list of referred fonts
|
2000-05-27 05:05:03 +00:00
|
|
|
if (flags & font::FONT_VIRTUAL) {
|
2000-05-26 00:00:15 +00:00
|
|
|
QIntDictIterator<font> it(vf_table);
|
|
|
|
while( it.current() ) {
|
2000-05-27 05:05:03 +00:00
|
|
|
it.current()->flags |= font::FONT_IN_USE;
|
2000-05-26 00:00:15 +00:00
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-05-27 05:05:03 +00:00
|
|
|
|
|
|
|
/** Returns a pointer to glyph number ch in the font, or NULL, if this
|
|
|
|
number does not exist. This function first reads the bitmap of the
|
|
|
|
character from the PK-file, if necessary */
|
|
|
|
|
|
|
|
struct glyph *font::glyphptr(unsigned int ch) {
|
|
|
|
|
|
|
|
struct glyph *g = glyphtable+ch;
|
|
|
|
if (g->bitmap.bits == NULL) {
|
|
|
|
if (g->addr == 0) {
|
2000-07-13 15:50:19 +00:00
|
|
|
kdError() << i18n("Character %1 not defined in font %2").arg(ch).arg(fontname) << endl;
|
2000-05-27 05:05:03 +00:00
|
|
|
g->addr = -1;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (g->addr == -1)
|
|
|
|
return NULL; /* previously flagged missing char */
|
|
|
|
|
|
|
|
if (file == NULL) {
|
|
|
|
file = xfopen(filename, OPEN_MODE);
|
|
|
|
if (file == NULL) {
|
2000-07-08 11:10:43 +00:00
|
|
|
oops(QString(i18n("Font file disappeared: %1")).arg(filename) );
|
2000-05-27 05:05:03 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Fseek(file, g->addr, 0);
|
|
|
|
read_PK_char(ch);
|
|
|
|
timestamp = ++current_timestamp;
|
|
|
|
|
|
|
|
if (g->bitmap.bits == NULL) {
|
|
|
|
g->addr = -1;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return g;
|
|
|
|
}
|