home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
g
/
gs241j11.zip
/
ZKFSNF.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-22
|
13KB
|
574 lines
/*
* zkfsnf.c --- Kanji font operator for X11R4 SNF format font file
*
* Copyright (C) 1991 Norio Katayama.
* Aug. 28, 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 */
/* X11 headers */
#undef min /* min and max are defined in X11/misc.h */
#undef max
#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 "fontstruct.h"
#include "bdftosnf.h"
#include "snfstruct.h"
/* DEFINITIONS BELOW ARE MACHINE DEPENDENT */
#ifdef sony
# define bitOrder MSBFirst
# define byteOrder MSBFirst
# define scanUnit 1
# ifdef bsd43
# define glyphPad 2
# else
# define glyphPad 1
# endif
#else
# define bitOrder DEFAULTBITORDER
# define byteOrder DEFAULTBYTEORDER
# define scanUnit DEFAULTSCANUNIT
# define glyphPad DEFAULTGLPAD
#endif
/* 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 snfimage(P9(char *, int, int *, int *, byte *, int,
gs_matrix *, floatp *, floatp *));
/*
* zkfsnf
*/
int
zkfsnf(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, "zkfsnf")) == 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 = snfimage(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, "zkfsnf");
return 0;
}
/* -------- Initialization procedure -------- */
op_def zkfsnf_op_defs[] = {
{"5kfsnf", zkfsnf},
op_def_end(0)
};
/*---------- The part below is copied from input.c and modified. ---------*/
/*-------- input.c is included in snftobdf written by Mark Leisher. ------*/
/*
* Copyright (C) 1990 Mark Leisher.
*
* Author: Mark Leisher (mleisher@nmsu.edu)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* A copy of the GNU General Public License can be obtained from this
* program's author (send electronic mail to mleisher@nmsu.edu) or from
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
* 02139, USA.
*
*/
#define ReallyNonExistent(pci) \
((((pci).metrics.leftSideBearing + (pci).metrics.rightSideBearing) == 0) && \
(((pci).metrics.ascent + (pci).metrics.descent) == 0))
private void
invertbits(unsigned char *buf, int count)
{
int i, n, m;
unsigned char c, oc;
for ( i = 0; i < count; i++ ) {
c = buf[i];
oc = 0;
for (n=0, m=7; n < 8; n++, m--) {
oc |= ((c >> n) & 1) << m;
}
buf[i] = oc;
}
}
private void
invert2(unsigned char *buf, int count)
{
int i;
unsigned char c;
for ( i = 0; i < count; i += 2) {
c = buf[i];
buf[i] = buf[i+1];
buf[i+1] = c;
}
}
private void
invert4(unsigned char *buf, int count)
{
int i;
unsigned char c;
for (i = 0; i < count; i += 4) {
c = buf[i];
buf[i] = buf[i+3];
buf[i+3] = c;
c = buf[i+1];
buf[i+1] = buf[i+2];
buf[i+2] = c;
}
}
private int
GetSNFInfo(char *file, TempFont **ptf)
{
int fd, i, size;
char *strings;
long offset;
TempFont *tf;
if((fd = open(file, 0)) < 0)
return e_undefinedfilename;
if((tf = (TempFont *)malloc(sizeof(TempFont))) == 0) {
close(fd);
return e_VMerror;
}
offset = 0;
/* FontInfo */
size = BYTESOFFONTINFO(tf->pFI);
if((tf->pFI = (FontInfoPtr)malloc(size)) == 0) {
close(fd);
return e_VMerror;
}
if(read(fd, tf->pFI, size) != size) {
close(fd);
return e_ioerror;
}
if (tf->pFI->version1 != FONT_FILE_VERSION ||
tf->pFI->version2 != FONT_FILE_VERSION)
fprintf(stderr, "Warning: %s is old style BDF\n", file);
if(lseek(fd, offset += size, 0) < 0) {
close(fd);
return e_ioerror;
}
/* CharInfo */
size = BYTESOFCHARINFO(tf->pFI);
if((tf->pCI = (CharInfoPtr)malloc(size)) == 0) {
close(fd);
return e_VMerror;
}
if(read(fd, tf->pCI, size) != size) {
close(fd);
return e_ioerror;
}
if(lseek(fd, offset += size, 0) < 0) {
close(fd);
return e_ioerror;
}
/* Glyphs */
tf->pGlyphs = (unsigned char *)offset;
if(lseek(fd, offset += BYTESOFGLYPHINFO(tf->pFI), 0) < 0) {
close(fd);
return e_ioerror;
}
/* FontProp */
size = BYTESOFPROPINFO(tf->pFI);
if((tf->pFP = (FontPropPtr)malloc(size)) == 0) {
close(fd);
return e_VMerror;
}
if(read(fd, tf->pFP, size) != size) {
close(fd);
return e_ioerror;
}
if(lseek(fd, offset += size, 0) < 0) {
close(fd);
return e_ioerror;
}
/* strings */
size = BYTESOFSTRINGINFO(tf->pFI);
if((strings = (char *)malloc(size)) == 0) {
close(fd);
return e_VMerror;
}
if(read(fd, strings, size) != size) {
close(fd);
return e_ioerror;
}
if(lseek(fd, offset += size, 0) < 0) {
close(fd);
return e_ioerror;
}
/* inkMetrics */
if (tf->pFI->inkMetrics) {
if((tf->pInkMin = (CharInfoPtr)
malloc(3 * sizeof(CharInfoRec))) == 0) {
close(fd);
return e_VMerror;
}
size = sizeof(CharInfoRec) * 3;
if(read(fd, tf->pInkMin, size) != size) {
close(fd);
return e_ioerror;
}
tf->pInkMax = tf->pInkMin + 1;
tf->pInkCI = tf->pInkMax + 1;
}
for (i = 0; i < tf->pFI->nProps; i++) {
tf->pFP[i].name += (int)strings;
if (tf->pFP[i].indirect)
tf->pFP[i].value += (int)strings;
}
*ptf = tf;
return(fd);
}
private int
code2num(TempFont *tf, 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
GetSNFBitmap(int fd, 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)
{
CharInfoPtr pCI = tf->pCI;
int charnum;
int ht, wd, gbp, wid, bytes, glyphbytes;
int i, j = 0, count = 0;
unsigned char *bitmap, *ptr;
if((charnum = code2num(tf, char_code)) < 0) {
if((charnum = code2num(tf, tf->pFI->chDefault)) < 0)
return e_rangecheck;
}
else {
if (!pCI[charnum].exists || ReallyNonExistent(pCI[charnum]))
if((charnum = code2num(tf, tf->pFI->chDefault)) < 0)
return e_rangecheck;
}
ht = pCI[charnum].metrics.descent + pCI[charnum].metrics.ascent;
wd = pCI[charnum].metrics.rightSideBearing -
pCI[charnum].metrics.leftSideBearing;
gbp = GLWIDTHBYTESPADDED(wd, glyphPad);
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, "GetSNFBitmap(bitmap)")) == 0)
return e_VMerror;
if(lseek(fd, tf->pGlyphs + pCI[charnum].byteOffset, 0) < 0)
return e_ioerror;
if(read(fd, bitmap, glyphbytes) != glyphbytes)
return e_ioerror;
if (bitOrder == LSBFirst)
invertbits(ptr, glyphbytes);
if (bitOrder != byteOrder) {
if (scanUnit == 2)
invert2(ptr, glyphbytes);
else if (scanUnit == 4)
invert4(ptr, glyphbytes);
}
for (i = 0; i < ht; i++) {
for (j = 0; j < wid; j++)
bmap[count++] = *ptr++;
ptr += (gbp - wid);
}
gs_free((char *)bitmap, glyphbytes, 1, "GetSNFBitmap(bitmap)");
/* Retrieve size */
*pixel_size = tf->pFI->fontAscent + tf->pFI->fontDescent;
for(i = 0; i< tf->pFI->nProps; i++) {
if(strcmp((char *)tf->pFP[i].name, "PIXEL_SIZE") == 0)
*pixel_size = tf->pFP[i].value;
}
if(*pixel_size == 0)
return e_invalidfont;
/* Set Metrics Information */
*font_ascent = tf->pFI->fontAscent;
*font_descent = tf->pFI->fontDescent;
*width = wd;
*height = ht;
*wx = pCI[charnum].metrics.characterWidth;
*wy = 0;
*llx = pCI[charnum].metrics.leftSideBearing;
*lly = - pCI[charnum].metrics.descent;
*urx = pCI[charnum].metrics.rightSideBearing;
*ury = pCI[charnum].metrics.ascent;
return 0;
}
/*--------------------------- end of input.c --------------------------*/
/*
* Hash Index Routines
*/
typedef struct index_item_s {
struct index_item_s *next;
char *str;
int fd;
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, int fd, 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->fd = fd;
item->tf = tf;
hash_index[key] = item;
return 0;
}
/* search */
private int
search(char *str, int *fd, TempFont **tf)
{
int key = hash((unsigned char *)str);
index_item *item;
item = hash_index[key];
while(item != 0) {
if(strcmp(item->str, str) == 0) {
*fd = item->fd;
*tf = item->tf;
return 1;
}
item = item->next;
}
return 0;
}
/*
* Open SNF Font File
*/
private int
OpenSNFFont(char *file, TempFont **ptf)
{
int fd, code;
if(search(file, &fd, ptf))
return fd;
else {
if((fd = GetSNFInfo(file, ptf)) < 0)
return fd;
if((code = store(file, fd, *ptf)) < 0)
return code;
return fd;
}
}
/*
* Retrieve Font Image
*/
private int
snfimage(char *file, int jis_code,
int *width, int *height, byte *bitmap, int length,
gs_matrix *pmat, floatp *wx, floatp *wy)
{
int code, fd, pixel_size;
int font_ascent, font_descent;
int w_x, w_y, ll_x, ll_y, ur_x, ur_y;
floatp dx, dy, scale;
gs_matrix smat, tmat;
TempFont *tf;
if((fd = OpenSNFFont(file, &tf)) < 0)
return fd;
if((code = GetSNFBitmap(fd, tf, jis_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;
}