📄 pklib.c
字号:
/* * pklib.c * * This file is part of the ttf2pk package. * * Copyright 1997-1999, 2000 by * Frederic Loyer <loyer@ensta.fr> * Werner Lemberg <wl@gnu.org> *//* * This code has been derived from the program gsftopk. * Here the original copyright. *//* * Copyright (c) 1994 Paul Vojta. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include <stdio.h>#include <stdlib.h>#include <stddef.h> /* for size_t */#include <string.h>#include <errno.h>#include <ctype.h>#include "newobj.h"#include "pklib.h"#include "errormsg.h"#include "filesrch.h"#ifndef MAXPATHLEN#define MAXPATHLEN 256#endif#define PK_PRE (char)247#define PK_ID 89#define PK_POST (char)245#define PK_NOP (char)246int dpi;FILE *pk_file;/* * Information from the .tfm file. */int tfm_lengths[12];#define lh tfm_lengths[1]#define bc tfm_lengths[2]#define ec tfm_lengths[3]#define nw tfm_lengths[4]long checksum;long design;byte width_index[256];long tfm_widths[256];/* * Information on the bitmap currently being worked on. */byte *bitmap;int width;int skip;int height;int hoff;int voff;int bytes_wide;size_t bm_size;byte *bitmap_end;int pk_len;/* * Here's the path searching stuff. First the typedefs and variables. */static char searchpath[MAXPATHLEN + 1];#define HUNKSIZE (MAXPATHLEN + 2)struct spacenode /* used for storage of directory names */{ struct spacenode *next; char *sp_end; /* end of data for this chunk */ char sp[HUNKSIZE];} firstnode;static FILE *search_tfm(char **name){ char *p; FILE *f; p = TeX_search_tfm(name); if (p == NULL) return NULL; strcpy(searchpath, p); f = fopen(searchpath, "rb"); return f;}static longgetlong(FILE *f){ unsigned long value; value = (unsigned long)getc(f) << 24; value |= (unsigned long)getc(f) << 16; value |= (unsigned long)getc(f) << 8; value |= (unsigned long)getc(f); return value;}char line[82];static byte masks[] = {0, 1, 3, 7, 017, 037, 077, 0177, 0377};byte flag;int pk_dyn_f;int pk_dyn_g;int base; /* cost of this character if pk_dyn_f = 0 */int deltas[13]; /* cost of increasing pk_dyn_f from i to i+1 *//* * Add up statistics for putting out the given shift count. */static voidtallyup(int n){ int m; if (n > 208) { ++base; n -= 192; for (m = 0x100; m != 0 && m < n; m <<= 4) base += 2; if (m != 0 && (m = (m - n) / 15) < 13) deltas[m] += 2; } else if (n > 13) ++deltas[(208 - n) / 15]; else --deltas[n - 1];}/* * Routines for storing the shift counts. */static Boolean odd = False;static byte part;static voidpk_put_nyb(int n){ if (odd) { *bitmap_end++ = (part << 4) | n; odd = False; } else { part = n; odd = True; }}static voidpk_put_long(int n){ if (n >= 16) { pk_put_nyb(0); pk_put_long(n / 16); } pk_put_nyb(n % 16);}static voidpk_put_count(int n){ if (n > pk_dyn_f) { if (n > pk_dyn_g) pk_put_long(n - pk_dyn_g + 15); else { pk_put_nyb(pk_dyn_f + (n - pk_dyn_f + 15) / 16); pk_put_nyb((n - pk_dyn_f - 1) % 16); } } else pk_put_nyb(n);}static voidtrim_bitmap(void){ byte *p; byte mask; /* clear out garbage bits in bitmap */ if (width % 8 != 0) { mask = ~masks[8 - width % 8]; for (p = bitmap + bytes_wide - 1; p < bitmap_end; p += bytes_wide) *p &= mask; } /* Find the bounding box of the bitmap. */ /* trim top */ skip = 0; mask = 0; for (;;) { if (bitmap >= bitmap_end) /* if bitmap is empty */ { width = height = hoff = voff = 0; return; } p = bitmap + bytes_wide; while (p > bitmap) mask |= *--p; if (mask) break; ++skip; bitmap += bytes_wide; } height -= skip; voff -= skip;#ifdef DEBUG if (skip < 2 || skip > 3) printf("Character has %d empty rows at top\n", skip);#endif /* trim bottom */ skip = 0; mask = 0; for (;;) { p = bitmap_end - bytes_wide; while (p < bitmap_end) mask |= *p++; if (mask) break; ++skip; bitmap_end -= bytes_wide; } height -= skip;#ifdef DEBUG if (skip < 2 || skip > 3) printf("Character has %d empty rows at bottom\n", skip);#endif /* trim right */ skip = 0; --width; for (;;) { mask = 0; for (p = bitmap + width / 8; p < bitmap_end; p += bytes_wide) mask |= *p; if (mask & (0x80 >> (width % 8))) break; --width; ++skip; } ++width;#ifdef DEBUG if (skip < 2 || skip > 3) printf("Character has %d empty columns at right\n", skip);#endif /* trim left */ skip = 0; for (;;) { mask = 0; for (p = bitmap + skip / 8; p < bitmap_end; p += bytes_wide) mask |= *p; if (mask & (0x80 >> (skip % 8))) break; ++skip; } width -= skip; hoff -= skip;#ifdef DEBUG if (skip < 2 || skip > 3) printf("Character has %d empty columns at left\n", skip);#endif bitmap += skip / 8; skip = skip % 8;}/* * Pack the bitmap using the rll method. (Return false if it's better * to just pack the bits.) */static Booleanpk_rll_cvt(void){ static int *counts = NULL; /* area for saving bit counts */ static int maxcounts = 0; /* size of this area */ unsigned int ncounts; /* max to allow this time */ int *nextcount; /* next count value */ int *counts_end; /* pointer to end */ byte *rowptr; byte *p; byte mask; byte *rowdup; /* last row checked for dup */ byte paint_switch; /* 0 or 0xff */ int bits_left; /* bits left in row */ int cost; int i; /* Allocate space for bit counts. */ ncounts = (width * height + 3) / 4; if (ncounts > maxcounts) { if (counts != NULL) free(counts); counts = (int *)mymalloc((ncounts + 2) * sizeof (int)); maxcounts = ncounts; } counts_end = counts + ncounts; /* Form bit counts and collect statistics */ base = 0; memset(deltas, 0, sizeof (deltas)); rowdup = NULL; /* last row checked for duplicates */ p = rowptr = bitmap; mask = 0x80 >> skip; flag = 0; paint_switch = 0; if (*p & mask) { flag = 8; paint_switch = 0xff; } bits_left = width; nextcount = counts; while (rowptr < bitmap_end) /* loop over shift counts */ { int shift_count = bits_left; for (;;) { if (bits_left == 0) { if ((p = rowptr += bytes_wide) >= bitmap_end) break; mask = 0x80 >> skip; bits_left = width; shift_count += width; } if (((*p ^ paint_switch) & mask) != 0) break; --bits_left; mask >>= 1; if (mask == 0) { ++p;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -