|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T t
Length: 5417 (0x1529)
Types: TextFile
Names: »tfmfont.c«
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
└─⟦this⟧ »./DVIware/laser-setters/umd-dvi/lib/tfmfont.c«
/*
* Copyright (c) 1987 University of Maryland Department of Computer Science.
* All rights reserved. Permission to copy for any purpose is hereby granted
* so long as this copyright notice remains intact.
*/
#ifndef lint
static char rcsid[] = "$Header: tfmfont.c,v 2.4 87/06/16 18:29:18 chris Exp $";
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "types.h"
#include "conv.h"
#include "font.h"
#include "tfm.h"
/*
* TFM font operations. This defines three fonts:
*
* box - prints as little square boxes, outlining what TeX
* thinks is the character.
* blank - prints as entirely blank.
* invis - prints as entirely blank.
*
* The first two also complain that no font is available in the
* requested size; these are intended to be used as a last resort
* so that users can always print DVI files. You should configure
* in exactly one of box or blank.
*
* TODO:
* base box edge widths on Conversion.c_dpi
*/
int box_read(), blank_read(), invis_read();
int tfm_getgly(), tfm_rasterise(), tfm_freefont();
/* magnifications are unused in tfm fonts */
struct fontops boxops = /* `boxtops'? Is this a cereal driver? */
{ "box", 0.0, box_read, tfm_getgly, tfm_rasterise, tfm_freefont };
struct fontops blankops =
{ "blank", 0.0, blank_read, tfm_getgly, tfm_rasterise, tfm_freefont };
struct fontops invisops =
{ "invis", 0.0, invis_read, tfm_getgly, tfm_rasterise, tfm_freefont };
/*
* Local info.
*/
struct tfm_details {
int tfm_edge; /* box edge widths, in pixels */
struct conversion tfm_conv; /* conv. from scaled pts to pixels */
struct tfmdata tfm_data; /* the TFM file data */
};
/*
* Get the tfm_details from font f.
*/
#define ftotfm(f) ((struct tfm_details *) (f)->f_details)
extern int errno;
char *malloc();
/*
* Read a Box font.
*/
static int
box_read(f)
struct font *f;
{
return (do_read(f, 0, 1));
}
/*
* Read a Blank font.
*/
static int
blank_read(f)
struct font *f;
{
return (do_read(f, 1, 1));
}
/*
* Read an Invisible font.
*/
static int
invis_read(f)
struct font *f;
{
return (do_read(f, 1, 0));
}
/*
* Read a TFM font. It is blank if `blank'; complain if `complain'.
*/
static int
do_read(f, blank, complain)
register struct font *f;
int blank, complain;
{
register struct tfm_details *tfm;
FILE *fd;
if ((fd = fopen(f->f_path, "r")) < 0)
return (-1);
if ((tfm = (struct tfm_details *) malloc(sizeof (*tfm))) == NULL)
goto fail;
if (readtfmfile(fd, &tfm->tfm_data, blank))
goto fail;
if (blank)
tfm->tfm_edge = 0;
else {
tfm->tfm_edge = 2; /* XXX should be based on dpi */
tfm->tfm_conv = Conversion;
tfm->tfm_conv.c_fromsp *= DMagFactor(f->f_scaled);
/* XXX !data abstraction */
}
if (FontHasGlyphs(f, tfm->tfm_data.t_hdr.th_bc,
tfm->tfm_data.t_hdr.th_ec + 1))
goto fail;
f->f_details = (char *) tfm;
(void) fclose(fd);
if (complain)
error(0, 0, "Warning: no font for %s", Font_TeXName(f));
return (0);
fail:
(void) fclose(fd);
if (tfm != NULL)
free((char *) tfm);
return (-1);
}
/*
* Obtain the specified range of glyphs.
*/
static int
tfm_getgly(f, l, h)
register struct font *f;
int l;
register int h;
{
register struct tfm_details *tfm = ftotfm(f);
register struct glyph *g;
register int i;
register struct char_info_word *ci;
#define t (&tfm->tfm_data)
i32 ScaleOneWidth();
#define ftop(fix) cfromSP(&tfm->tfm_conv, ScaleOneWidth(fix, f->f_dvimag))
for (i = l; i < h; i++) {
ci = &t->t_ci[i - t->t_hdr.th_bc];
/* zero widths mark invalid characters */
if (ci->ci_width == 0)
continue;
g = f->f_gly[i];
g->g_flags = GF_VALID;
g->g_tfmwidth = t->t_width[UnSign8(ci->ci_width)];
if (tfm->tfm_edge != 0) {
g->g_xorigin = 0;
g->g_yorigin = ftop(t->t_height[T_CI_H(ci)]);
g->g_width = ftop(g->g_tfmwidth);
g->g_height = g->g_yorigin +
ftop(t->t_depth[T_CI_D(ci)]);
}
}
return (0);
#undef t
}
/*
* Obtain rasters for the specified glyphs.
*
* IGNORES tfm->tfm_edge: 2 HARDCODED FOR NOW
*/
static int
tfm_rasterise(f, l, h)
struct font *f;
int l, h;
{
register struct glyph *g;
register char *p;
register int w, j, i;
struct tfm_details *tfm = ftotfm(f);
#define EDGE 2
if (tfm->tfm_edge == 0)
return;
if (tfm->tfm_edge != 2) panic("tfm_rasterise");
for (i = l; i < h; i++) {
g = f->f_gly[i];
if ((g->g_flags & GF_VALID) == 0 || !HASRASTER(g))
continue;
w = (g->g_width + 7) >> 3;
p = malloc((unsigned) (g->g_height * w));
if (p == NULL)
return (-1);
g->g_raster = p;
g->g_rotation = ROT_NORM;
if (g->g_width < 2 * EDGE) {
w = 2 * EDGE - g->g_width;
for (j = g->g_height; --j >= 0;)
*p++ = 0xf0 << w;
} else {
bzero(p, g->g_height * w);
for (j = 0; j < g->g_height;) {
if (j < EDGE || j >= g->g_height - EDGE) {
register int k = w;
while (--k > 0)
*p++ = 0xff;
*p++ = 0xff << ((8 - g->g_width) & 7);
j++;
continue;
}
/* the following depends on EDGE==2 */
*p = 0xc0;
p += w - ((g->g_width & 7) == 1 ? 2 : 1);
*p++ |= 0xc0 >> ((g->g_width - EDGE) & 7);
if ((g->g_width & 7) == 1)
*p++ = 0x80;
/* end dependencies */
if (++j == EDGE && g->g_height >= 2 * EDGE) {
register int n = g->g_height - EDGE;
p += (n - j) * w;
j = n;
}
}
}
}
return (0);
}
/*
* Discard the font details.
*/
static
tfm_freefont(f)
struct font *f;
{
free(f->f_details);
}