home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
g
/
gs241j11.zip
/
ZKFPCF.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-01
|
23KB
|
929 lines
/*
* zkfpcf.c --- Kanji font operator for X11R5 PCF format file
*
* Copyright (C) 1991 Norio Katayama.
* Sep. 10, 1991 Programmed by N.Katayama (katayama@nacsis.ac.jp)
*/
#include "memory_.h"
#include "ghost.h"
#include "oper.h"
#include "errors.h"
#include "gsmatrix.h"
#include "state.h"
#include "store.h"
#define B_X_CL 500 /* horizontal center in BuildChar */
#define B_Y_CL 400 /* vertical center in BuildChar */
/* Imported procedures */
extern int kf_is_vchar(P1(int));
extern int kf_vmatrix(P5(int, floatp, floatp, gs_rect *, gs_matrix *));
extern int gs_imagebbox(P6(int width, int height, int bool,
gs_matrix *pmat, byte *image, gs_rect *));
/* Forward declaration */
private int pcfimage(P9(char *, int, int *, int *, byte *, int,
gs_matrix *, floatp *, floatp *));
/*
* zkfpcf
*/
int
zkfpcf(register os_ptr op)
{
char *buffer;
int code, len, width, height, length;
int jis_code, wmode;
byte *bitmap;
floatp w0x, w0y;
gs_matrix *pmat, vmat, imat;
gs_rect bbox;
check_type(op[-4], t_integer); /* JIS Code */
check_type(op[-3], t_integer); /* WMode */
if((code = write_matrix(op - 2)) < 0) /* ImageMatrix */
return code;
check_type(op[-1], t_string); /* ImageString */
check_type(op[0], t_string); /* FileName */
len = r_size(op);
if((buffer = gs_malloc(len + 1, 1, "zkfpcf")) == 0)
return e_VMerror;
memcpy(buffer, (char *)op->value.bytes, len);
buffer[len] = 0;
jis_code = op[-4].value.intval;
wmode = op[-3].value.intval;
bitmap = op[-1].value.bytes;
length = r_size(op - 1);
pmat = (gs_matrix *)op[-2].value.refs;
if((code = pcfimage(buffer, jis_code,
&width, &height, bitmap, length,
pmat, &w0x, &w0y)) < 0)
return code;
if((code = gs_imagebbox(width, height, 1, pmat, bitmap, &bbox)) < 0)
return code;
if(wmode && kf_is_vchar(jis_code)) {
kf_vmatrix(jis_code,
(floatp)B_X_CL, (floatp)B_Y_CL, &bbox, &vmat);
gs_matrix_invert(&vmat, &imat);
gs_matrix_multiply(&imat, pmat, pmat);
}
/* Push results */
/* w0x w0y llx lly urx ury width height bool matrix bitmap */
push(6);
make_real(op - 10, w0x);
make_real(op - 9, w0y);
make_real(op - 8, bbox.p.x);
make_real(op - 7, bbox.p.y);
make_real(op - 6, bbox.q.x);
make_real(op - 5, bbox.q.y);
make_int(op - 4, width);
make_int(op - 3, height);
make_bool(op - 2 , 1);
make_tasv(op - 1, t_array, a_all, 6, refs, (ref *)pmat);
make_tasv(op, t_string, a_all, length, bytes, bitmap);
gs_free(buffer, len + 1, 1, "zkfpcf");
return 0;
}
/* -------- Initialization procedure -------- */
op_def zkfpcf_op_defs[] = {
{"5kfpcf", zkfpcf},
op_def_end(0)
};
/*--------- The part below is written with reference to pcfread.c -------*/
/*------------- which is included in MIT X11R5 distribution. -------------*/
/*
* $XConsortium: pcfread.c,v 1.7 91/07/22 22:58:57 keith Exp $
*
* Copyright 1990 Massachusetts Institute of Technology
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. M.I.T. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Keith Packard, MIT X Consortium
*/
/* X11 headers */
#undef min /* min and max are defined in X11/misc.h */
#undef max
#undef private /* private is used as a variable name in fontstruct.h */
#define name _name /* circumvent the conflict between type and ident */
#ifdef BSD4_2 /* circumvent the conflict between Xfuncs.h and memory_.h */
#define bcopy _bcopy
#define bzero _bzero
#include <X11/Xfuncs.h>
#undef bcopy
#undef bzero
#endif
#include <X11/X.h>
#include <X11/Xproto.h>
#include "servermd.h"
#include "fontmisc.h"
#include "fontstruct.h"
#include "pcf.h"
#ifdef NOPRIVATE
#define private /* */
#else
#define private static
#endif
/* Temporary Font Information */
typedef struct TempFontRec {
PCFTablePtr tables;
int ntables;
FontInfoPtr pFI;
CharInfoPtr pCI;
CharInfoPtr *encoding;
CARD32 bitmap_format;
char *strings;
int pixel_size;
} TempFont, *TempFontPtr;
#define ReallyNonExistent(pci) \
((((pci)->metrics.leftSideBearing + \
(pci)->metrics.rightSideBearing) == 0) && \
(((pci)->metrics.ascent + (pci)->metrics.descent) == 0))
private CARD32
pcfGetLSB32(FILE *fp)
{
unsigned char buffer[4];
CARD32 c;
fread(buffer, 1, 4, fp);
c = (unsigned long)buffer[0];
c |= (unsigned long)buffer[1] << 8;
c |= (unsigned long)buffer[2] << 16;
c |= (unsigned long)buffer[3] << 24;
return c;
}
private long
pcfGetINT32(FILE *fp, CARD32 format)
{
unsigned char buffer[4];
long c;
fread(buffer, 1, 4, fp);
if(PCF_BYTE_ORDER(format) == MSBFirst) {
c = (unsigned long)buffer[0] << 24;
c |= (unsigned long)buffer[1] << 16;
c |= (unsigned long)buffer[2] << 8;
c |= (unsigned long)buffer[3];
}
else {
c = (unsigned long)buffer[0];
c |= (unsigned long)buffer[1] << 8;
c |= (unsigned long)buffer[2] << 16;
c |= (unsigned long)buffer[3] << 24;
}
return c;
}
private int
pcfGetINT16(FILE *fp, CARD32 format)
{
unsigned char buffer[2];
int c;
fread(buffer, 1, 2, fp);
if(PCF_BYTE_ORDER(format) == MSBFirst) {
c = (unsigned int)buffer[0] << 8;
c |= (unsigned int)buffer[1];
}
else {
c = (unsigned int)buffer[0];
c |= (unsigned int)buffer[1] << 8;
}
return c;
}
#define pcfGetINT8(fp, format) fgetc(fp)
private void
BitOrderInvert(unsigned char *ptr, int length)
{
int i, j, k;
unsigned char c;
for(i=0; i<length; i++, ptr++) {
c = 0;
for(j=0, k=7; j < 8; j++, k--)
c |= ((*ptr >> j) & 1) << k;
*ptr = c;
}
}
private void
TwoByteSwap(unsigned char *ptr, int length)
{
int i;
unsigned char c;
for(i=0; i<length; i += 2) {
c = ptr[i];
ptr[i] = ptr[i+1];
ptr[i+1] = c;
}
}
private void
FourByteSwap(unsigned char *ptr, int length)
{
int i;
unsigned char c;
for(i=0; i<length; i += 4) {
c = ptr[i];
ptr[i] = ptr[i+3];
ptr[i+3] = c;
c = ptr[i+1];
ptr[i+1] = ptr[i+2];
ptr[i+2] = c;
}
}
private int
pcfReadTOC(FILE *fp, PCFTablePtr *ptables, int *pcount)
{
CARD32 version;
PCFTablePtr tables;
int count;
int i;
version = pcfGetLSB32(fp);
if(version != PCF_FILE_VERSION)
return e_undefinedfilename;
count = pcfGetLSB32(fp);
if((tables = (PCFTablePtr)malloc(count * sizeof(PCFTableRec))) == 0)
return e_VMerror;
for(i=0; i<count; i++) {
tables[i].type = pcfGetLSB32(fp);
tables[i].format = pcfGetLSB32(fp);
tables[i].size = pcfGetLSB32(fp);
tables[i].offset = pcfGetLSB32(fp);
}
*ptables = tables;
*pcount = count;
return 0;
}
private int
pcfGetMetric(FILE *fp, CARD32 format, xCharInfo *metric)
{
metric->leftSideBearing = pcfGetINT16(fp, format);
metric->rightSideBearing = pcfGetINT16(fp, format);
metric->characterWidth = pcfGetINT16(fp, format);
metric->ascent = pcfGetINT16(fp, format);
metric->descent = pcfGetINT16(fp, format);
metric->attributes = pcfGetINT16(fp, format);
}
private int
pcfGetCompressedMetric(FILE *fp, CARD32 format, xCharInfo *metric)
{
metric->leftSideBearing = pcfGetINT8(fp, format) - 0x80;
metric->rightSideBearing = pcfGetINT8(fp, format) - 0x80;
metric->characterWidth = pcfGetINT8(fp, format) - 0x80;
metric->ascent = pcfGetINT8(fp, format) - 0x80;
metric->descent = pcfGetINT8(fp, format) - 0x80;
metric->attributes = 0;
}
private int
pcfSeekToType(FILE *fp, PCFTablePtr tables, int ntables, CARD32 type,
CARD32 *pformat, CARD32 *psize)
{
int i;
for(i=0; i<ntables; i++) {
if(tables[i].type == type) {
fseek(fp, tables[i].offset, 0);
*psize = tables[i].size;
*pformat = tables[i].format;
return 1;
}
}
return 0;
}
private int
pcfHasType(PCFTablePtr tables, int ntables, CARD32 type)
{
int i;
for (i = 0; i < ntables; i++)
if (tables[i].type == type)
return 1;
return 0;
}
private int
pcfGetProperties(FILE *fp, PCFTablePtr tables, int ntables,
FontInfoPtr pFontInfo, char **strings_return)
{
FontPropPtr props;
int nprops;
char *isStringProp;
CARD32 format, size;
int i, string_size;
char *strings;
/* font properties */
if(!pcfSeekToType(fp, tables, ntables, PCF_PROPERTIES, &format, &size))
return e_undefinedfilename;
format = pcfGetLSB32(fp);
if(!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
return e_undefinedfilename;
nprops = pcfGetINT32(fp, format);
if((props = (FontPropPtr)malloc(nprops * sizeof(FontPropRec))) == 0)
return e_VMerror;
if((isStringProp = (char *)malloc(nprops * sizeof(char))) == 0)
return e_VMerror;
for(i=0; i<nprops; i++) {
props[i].name = pcfGetINT32(fp, format);
isStringProp[i] = pcfGetINT8(fp, format);
props[i].value = pcfGetINT32(fp, format);
}
/* pad the property array */
/*
* clever here - nprops is the same as the number of odd-units read, as
* only isStringProp are odd length
*/
if (nprops & 3) {
i = 4 - (nprops & 3);
fseek(fp, i, 1);
}
string_size = pcfGetINT32(fp, format);
if((strings = (char *)malloc(string_size)) == 0)
return e_VMerror;
fread(strings, 1, string_size, fp);
pFontInfo->isStringProp = isStringProp;
pFontInfo->props = props;
pFontInfo->nprops = nprops;
*strings_return = strings;
return 0;
}
private int
pcfGetAccel(FontInfoPtr pFontInfo, FILE *fp,
PCFTablePtr tables, int ntables, CARD32 type)
{
CARD32 format;
CARD32 size;
if (!pcfSeekToType(fp, tables, ntables, type, &format, &size))
return e_undefinedfilename;
format = pcfGetLSB32(fp);
if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
!PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS))
return e_undefinedfilename;
pFontInfo->noOverlap = pcfGetINT8(fp, format);
pFontInfo->constantMetrics = pcfGetINT8(fp, format);
pFontInfo->terminalFont = pcfGetINT8(fp, format);
pFontInfo->constantWidth = pcfGetINT8(fp, format);
pFontInfo->inkInside = pcfGetINT8(fp, format);
pFontInfo->inkMetrics = pcfGetINT8(fp, format);
pFontInfo->drawDirection = pcfGetINT8(fp, format);
pFontInfo->anamorphic = FALSE;
/* natural alignment */ pcfGetINT8(fp, format);
pFontInfo->fontAscent = pcfGetINT32(fp, format);
pFontInfo->fontDescent = pcfGetINT32(fp, format);
pFontInfo->maxOverlap = pcfGetINT32(fp, format);
pcfGetMetric(fp, format, &pFontInfo->minbounds);
pcfGetMetric(fp, format, &pFontInfo->maxbounds);
if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
pcfGetMetric(fp, format, &pFontInfo->ink_minbounds);
pcfGetMetric(fp, format, &pFontInfo->ink_maxbounds);
} else {
pFontInfo->ink_minbounds = pFontInfo->minbounds;
pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
}
return 0;
}
private int
GetTempFont(char *file, FILE **pfp, TempFont **ptf)
{
int i;
int nencoding, nmetrics, nbitmaps, sizebitmaps;
CARD32 format, size, bitmapSizes[GLYPHPADOPTIONS];
int hasBDFAccelerators;
long offset;
FILE *fp;
TempFont *tf;
if((fp = fopen(file, "r")) == NULL)
return e_undefinedfilename;
if((tf = (TempFont *)malloc(sizeof(TempFont))) == 0) {
fclose(fp);
return e_VMerror;
}
if((tf->pFI = (FontInfoPtr)malloc(sizeof(FontInfoRec))) == 0) {
fclose(fp);
return e_VMerror;
}
if(pcfReadTOC(fp, &tf->tables, &tf->ntables) < 0) {
fclose(fp);
return e_undefinedfilename;
}
/* properties */
if(pcfGetProperties(fp, tf->tables, tf->ntables,
tf->pFI, &tf->strings) < 0) {
fclose(fp);
return e_undefinedfilename;
}
/* Use the old accelerators if no BDF accelerators are in the file */
hasBDFAccelerators =
pcfHasType(tf->tables, tf->ntables, PCF_BDF_ACCELERATORS);
if (!hasBDFAccelerators) {
if(pcfGetAccel(tf->pFI, fp,
tf->tables, tf->ntables, PCF_ACCELERATORS) < 0) {
fclose(fp);
return e_undefinedfilename;
}
}
/* metrics */
if(!pcfSeekToType(fp, tf->tables, tf->ntables,
PCF_METRICS, &format, &size)) {
fclose(fp);
return e_undefinedfilename;
}
format = pcfGetLSB32(fp);
if(!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
!PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
fclose(fp);
return e_undefinedfilename;
}
if(PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
nmetrics = pcfGetINT32(fp, format);
else
nmetrics = pcfGetINT16(fp, format);
if((tf->pCI = (CharInfoPtr)malloc(nmetrics * sizeof(CharInfoRec))) == 0) {
fclose(fp);
return e_undefinedfilename;
}
for(i=0; i<nmetrics; i++) {
if(PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
pcfGetMetric(fp, format, &tf->pCI[i].metrics);
else
pcfGetCompressedMetric(fp, format, &tf->pCI[i].metrics);
}
/* encoding */
if(pcfSeekToType(fp, tf->tables, tf->ntables,
PCF_BDF_ENCODINGS, &format, &size) < 0) {
fclose(fp);
return e_undefinedfilename;
}
format = pcfGetLSB32(fp);
if(!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
fclose(fp);
return e_undefinedfilename;
}
tf->pFI->firstCol = pcfGetINT16(fp, format);
tf->pFI->lastCol = pcfGetINT16(fp, format);
tf->pFI->firstRow = pcfGetINT16(fp, format);
tf->pFI->lastRow = pcfGetINT16(fp, format);
tf->pFI->defaultCh = pcfGetINT16(fp, format);
nencoding = (tf->pFI->lastCol - tf->pFI->firstCol + 1) *
(tf->pFI->lastRow - tf->pFI->firstRow + 1);
if((tf->encoding = (CharInfoPtr *)
calloc(nencoding, sizeof(CharInfoPtr))) == 0) {
fclose(fp);
return e_VMerror;
}
tf->pFI->allExist = TRUE;
for(i=0; i<nencoding; i++) {
if((offset = pcfGetINT16(fp, format)) == 0xFFFF) {
tf->pFI->allExist = FALSE;
tf->encoding[i] = 0;
}
else
tf->encoding[i] = tf->pCI + offset;
}
/* BDF style accelerators (i.e. bounds based on encoded glyphs) */
if(hasBDFAccelerators) {
if(pcfGetAccel(tf->pFI, fp, tf->tables, tf->ntables,
PCF_BDF_ACCELERATORS) < 0) {
fclose(fp);
return e_undefinedfilename;
}
}
/* bitmaps */
if(!pcfSeekToType(fp, tf->tables, tf->ntables,
PCF_BITMAPS, &format, &size) < 0) {
fclose(fp);
return e_undefinedfilename;
}
format = tf->bitmap_format = pcfGetLSB32(fp);
if(!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
fclose(fp);
return e_undefinedfilename;
}
nbitmaps = pcfGetINT32(fp, format);
if(nbitmaps != nmetrics) {
fclose(fp);
return e_undefinedfilename;
}
for(i=0; i<nbitmaps; i++)
tf->pCI[i].bits = (char *)pcfGetINT32(fp, format);
for(i=0; i<GLYPHPADOPTIONS; i++)
bitmapSizes[i] = pcfGetINT32(fp, format);
sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX(format)];
offset = ftell(fp);
for(i=0; i<nbitmaps; i++)
tf->pCI[i].bits += offset;
/* Retrieve properties */
tf->pixel_size = tf->pFI->fontAscent + tf->pFI->fontDescent;
for(i = 0; i< tf->pFI->nprops; i++) {
FontPropPtr pFP = tf->pFI->props;
char *prop_name = tf->strings + pFP[i].name;
int prop_value = pFP[i].value;
if(strcmp(prop_name, "PIXEL_SIZE") == 0)
tf->pixel_size = prop_value;
}
if(tf->pixel_size == 0)
return e_undefinedfilename;
/**********************************************
* NOTICE: BDF style accelerators are ignored *
**********************************************/
*pfp = fp;
*ptf = tf;
return 0;
}
private int
code2num(TempFont *tf, unsigned int code)
{
int row, col, ncols;
FontInfoPtr pFI = tf->pFI;
if((row = (code >> 8)) < pFI->firstRow ||
row > pFI->lastRow)
return -1;
if((col = (code & 0x00ff)) < pFI->firstCol ||
col > pFI->lastCol)
return -1;
ncols = pFI->lastCol - pFI->firstCol + 1;
return (row - pFI->firstRow) * ncols + col - pFI->firstCol;
}
private int
GetPCFBitmap(FILE *fp, TempFont *tf, unsigned int char_code,
int *width, int *height, byte *bmap, int length,
int *pixel_size, int *font_ascent, int *font_descent,
int *wx, int *wy, int *llx, int *lly, int *urx, int *ury)
{
int ht, wd, gbp, wid, bytes, glyphbytes;
int i, j, count;
unsigned char *bitmap, *ptr;
int charnum;
CharInfoPtr pCI;
if((charnum = code2num(tf, char_code)) == -1) {
if((charnum = code2num(tf, tf->pFI->defaultCh)) == -1)
return e_rangecheck;
}
else {
if(tf->encoding[charnum] == 0 ||
ReallyNonExistent(tf->encoding[charnum])) {
if((charnum = code2num(tf, tf->pFI->defaultCh)) == -1)
return e_rangecheck;
}
}
if((pCI = tf->encoding[charnum]) == 0) {
/* If the CharInfo does not exist, return blank character. */
*pixel_size = tf->pixel_size;
*font_ascent = tf->pFI->fontAscent;
*font_descent = tf->pFI->fontDescent;
*width = 0;
*height = 0;
length = 0;
*wx = tf->pFI->maxbounds.characterWidth;
*wy = 0;
*llx = tf->pFI->maxbounds.leftSideBearing;
*lly = - tf->pFI->maxbounds.descent;
*urx = tf->pFI->maxbounds.rightSideBearing;
*ury = tf->pFI->maxbounds.ascent;
return 0;
}
ht = pCI->metrics.descent + pCI->metrics.ascent;
wd = pCI->metrics.rightSideBearing - pCI->metrics.leftSideBearing;
gbp = BYTES_PER_ROW(wd, PCF_GLYPH_PAD(tf->bitmap_format));
wid = ((wd / 8) + ((wd % 8) ? 1 : 0));
bytes = ht * wid;
glyphbytes = gbp * ht;
if(bytes > length)
return e_rangecheck;
/* Read Glyph */
if((bitmap = ptr = (unsigned char *)
gs_malloc(glyphbytes, 1, "GetPCFBitmap(bitmap)")) == 0)
return e_VMerror;
if(fseek(fp, (long)pCI->bits, 0) < 0)
return e_ioerror;
if(fread(bitmap, 1, glyphbytes, fp) != glyphbytes)
return e_ioerror;
if (PCF_BIT_ORDER(tf->bitmap_format) != MSBFirst)
BitOrderInvert(ptr, glyphbytes);
if (PCF_BYTE_ORDER(tf->bitmap_format) !=
PCF_BIT_ORDER(tf->bitmap_format)) {
switch(PCF_SCAN_UNIT(tf->bitmap_format)) {
case 2:
TwoByteSwap(ptr, glyphbytes);
break;
case 4:
FourByteSwap(ptr, glyphbytes);
break;
}
}
count = 0;
for (i = 0; i < ht; i++) {
for (j = 0; j < wid; j++)
bmap[count++] = *ptr++;
ptr += (gbp - wid);
}
gs_free((char *)bitmap, glyphbytes, 1, "GetPCFBitmap(bitmap)");
/* Set Metrics Information */
*pixel_size = tf->pixel_size;
*font_ascent = tf->pFI->fontAscent;
*font_descent = tf->pFI->fontDescent;
*width = wd;
*height = ht;
*wx = pCI->metrics.characterWidth;
*wy = 0;
*llx = pCI->metrics.leftSideBearing;
*lly = - pCI->metrics.descent;
*urx = pCI->metrics.rightSideBearing;
*ury = pCI->metrics.ascent;
return 0;
}
/*--------------------------- end of pcfread --------------------------*/
/*
* Hash Index Routines
*/
typedef struct index_item_s {
struct index_item_s *next;
char *str;
FILE *fp;
TempFont *tf;
} index_item;
private index_item *hash_index[256];
/* Hash function */
private int
hash(unsigned char *str)
{
unsigned char hash;
for(hash = 0; *str != 0; str++)
hash ^= *str;
return hash;
}
/* store */
private int
store(char *str, FILE *fp, TempFont *tf)
{
int key = hash((unsigned char *)str);
index_item *item;
if((item = (index_item *)malloc(sizeof(index_item))) == 0)
return e_VMerror;
if((item->str = (char *)malloc(strlen(str) + 1)) == 0)
return e_VMerror;
strcpy(item->str, str);
item->next = hash_index[key];
item->fp = fp;
item->tf = tf;
hash_index[key] = item;
return 0;
}
/* search */
private int
search(char *str, FILE **fp, TempFont **tf)
{
int key = hash((unsigned char *)str);
index_item *item;
item = hash_index[key];
while(item != 0) {
if(strcmp(item->str, str) == 0) {
*fp = item->fp;
*tf = item->tf;
return 1;
}
item = item->next;
}
return 0;
}
/*
* Open PCF Font File
*/
private int
OpenPCFFont(char *file, FILE **pfp, TempFont **ptf)
{
int code;
if(search(file, pfp, ptf))
return 0;
else {
if((code = GetTempFont(file, pfp, ptf)) < 0)
return code;
if((code = store(file, *pfp, *ptf)) < 0)
return code;
return 0;
}
}
/*
* Kanji Code Conversion
*/
private unsigned int
jis2euc(unsigned int jis_code)
{
return jis_code | 0x8080;
}
private unsigned int
jis2sjis(unsigned int jis_code)
{
unsigned int j1, j2, s1, s2;
j1 = jis_code >> 8;
j2 = jis_code & 0xff;
if(j1 < 0x5f)
s1 = (j1 - 0x21) / 2 + 0x81;
else
s1 = (j1 - 0x5f) / 2 + 0xe0;
if(j1 & 1) {
if(j2 < 0x60)
s2 = j2 + 0x1f;
else
s2 = j2 + 0x20;
}
else
s2 = j2 + 0x7e;
return (s1 << 8 + s2);
}
private unsigned int
jis2cc(TempFont *tf, unsigned int jis_code)
{
int num;
if(((num = code2num(tf, 0x3021)) >= 0) && (tf->encoding[num] != 0)) {
/* suppose that the encoding is JIS */
return jis_code;
}
if(((num = code2num(tf, 0xB0A1)) >= 0) && (tf->encoding[num] != 0)) {
/* suppose that the encoding is EUC */
return jis2euc(jis_code);
}
if(((num = code2num(tf, 0x889F)) >= 0) && (tf->encoding[num] != 0)) {
/* suppose that the encoding is SJIS */
return jis2sjis(jis_code);
}
return jis_code;
}
/*
* Retrieve Font Image
*/
private int
pcfimage(char *file, int jis_code,
int *width, int *height, byte *bitmap, int length,
gs_matrix *pmat, floatp *wx, floatp *wy)
{
int code, pixel_size, font_ascent, font_descent;
int w_x, w_y, ll_x, ll_y, ur_x, ur_y;
unsigned int char_code;
floatp dx, dy, scale;
gs_matrix smat, tmat;
FILE *fp;
TempFont *tf;
if((code = OpenPCFFont(file, &fp, &tf)) < 0)
return code;
char_code = jis2cc(tf, jis_code);
if((code = GetPCFBitmap(fp, tf, char_code,
width, height, bitmap, length,
&pixel_size, &font_ascent, &font_descent,
&w_x, &w_y, &ll_x, &ll_y, &ur_x, &ur_y)) < 0)
return code;
/* Transform Image */
gs_make_identity(pmat);
scale = (floatp)B_Y_CL * 2.0 / (floatp)font_ascent;
gs_make_scaling(1.0 / scale, -1.0 / scale, &smat);
dx = (floatp)pixel_size / 2.0 - (floatp)B_X_CL / scale;
dy = (floatp)font_ascent;
gs_make_translation(dx, dy, &tmat);
gs_matrix_multiply(pmat, &smat, pmat);
gs_matrix_multiply(pmat, &tmat, pmat);
*wx = (floatp)B_X_CL * 2.0;
*wy = 0;
return 0;
}