/* * VF_Jg.c * * Originally Programmmed by Hideo "Sir MaNMOS" Morisita * New implementation by Hirotsugu Kakugawa * E-Mail: h.kakugawa@computer.org * * Edition History * 10 Nov 1993 * 20 Nov 1993 Debugged * 21 Nov 1993 ro, sl, ox, oy, fx, fy implemented * 20 Jan 1994 Added GetOutline2(). * 8 Mar 1994 Implemented Sony compatible outline extraction routine * 8 Mar 1994 Fixed small bugs and removed dead code * 11 Mar 1994 Changed draw routine * 3 Sep 1994 Changed type declaration of ConvXY() * 3 Feb 1995 Bug fix for left slant conversion. * 16 Mar 1995 Changed header reading routine not to read * everything at initialization. * 16 Mar 1995 Fixed memory leak in JGOpenFont(). * 6 May 1995 Dynamic Opening/Closing font file feature by H.Kakugawa. * 23 May 1995 Added range checking of char code. * 21 Mar 1996 Added range checking of a point in ReadXY(). * */ /* This file is part of VFlib * * Copyright (C) 1993-1998 Hirotsugu KAKUGAWA. All rights reserved. * * This file is part of the VFlib Library. This library is free * software; you can redistribute it and/or modify it under the terms of * the GNU Library General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your * option) any later version. This library 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 Library General Public License for more details. * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Capabilities interpretable by jg font objects: "ff" (str) -- Font file path (THIS IS NECESSARY) "fr" (bool) -- Frame font if defined "th" (bool) -- Thicken the char if defined "ro" (num) -- Rotate the char 90*n degrees in clockwise direction "rx" (bool) -- Reflect about x-axis if defined "ry" (bool) -- Reflect about y-axis if defined "sl" (num) -- Slant the char n/100 Corrrection Factors: "ox" (num) -- Offset for x-axis for vector font data (will be subtracted) "oy" (num) -- Offset for y-axis for vector font data (will be subtracted) "fx" (num) -- Factor for x-axis for vector font data "fy" (num) -- Factor for x-axis for vector font data Each point p0=(x0,y0) of vector font data is transformed in the following order: 1. addition of `offset' : (x1,y1)=(x0-x_offset, y0-y_offset) 2. magnification by `factor': (x2,y2)=(x1*x_factor, y2*y_factor) 3. computing of the slant 3. rotation in clockwise direction 4. reflection about x-axis 5. reflection about y-axis */ #include #include #include #include "config.h" #include "defs.h" #include #include "_VF.h" #include "VF.h" #include "VFcap.h" #define JG_MAX_VALUE 0x0fff #define JG_MAX_XY 0x07ff #define JG_XY_MASK 0x07ff #define JG_CMD_MASK 0x0800 #define JG_CODE_SIZE0 0x0582 #define JG_CODE_SIZE1 0x0bc0 #define JG_CODE_SIZE2 0x0d96 /*#define JG_CODE_SIZE2 0x0d3d*/ #define STATIC static #define CONV_X(x) \ ((unsigned int)(OUTLINE_OFFSET+((x)*OUTLINE_SIZE)/JG_MAX_XY)) #define CONV_Y(y) \ ((unsigned int)(OUTLINE_OFFSET+((y)*OUTLINE_SIZE)/JG_MAX_XY)) #define UNCONV_X(x) \ ((unsigned int)(JG_MAX_XY*((x)-OUTLINE_OFFSET))/OUTLINE_SIZE) #define UNCONV_Y(y) \ ((unsigned int)(JG_MAX_XY*((y)-OUTLINE_OFFSET))/OUTLINE_SIZE) #define EMPTY_PTR 0xffffffff struct s_font { int PrimFont; char *FontFileName; /* ff */ int Frame; /* fr */ int Thicken; /* th */ int Rotate; /* ro */ int XReflect; /* rx */ int YReflect; /* ry */ int Slant; /* sl */ int Xoffset; /* ox */ int Yoffset; /* oy */ int Xfactor; /* fx */ int Yfactor; /* fy */ double MatT1, MatT2, MatT3, MatT4, MatT5, MatT6; }; typedef struct s_font Font; Private int OpenFont(); Private int CloseFont(); Private int GetBitmap(); Private long *GetOutline(); Private long *GetOutline2(); Private int DrawOutline(); Private int FreeOutline(); Private int Link(); Private int Unlink(); Private void ConvXY(); int VF_Draw(); static int ReadCapa(); static int JGOpenFont(); static int JGCloseFont(); static int JGReadHeader(); static long* JGReadOutline(); static void InitBitStream(); static int ReadXY(); static unsigned long Read4Bytes(); static int Read1Byte(); static unsigned int Read12Bits(); static int CorrectSize(); static void Seek(); static long CurrentPos(); Private int jis2c(); Public FontObj* CreateFont_Jg(ent) char *ent; { Font *font; FontObj *fobj; if ((font = (Font*) malloc(sizeof(Font))) == NULL) return NULL; /* ERR: malloc err */ font->PrimFont = -1; if (ReadCapa(font, ent) < 0){ free(font); return NULL; } fobj = (FontObj*) malloc(sizeof(FontObj)); if (fobj == NULL){ free(font->FontFileName); free(font); return NULL; } fobj->ClassID = VF_FONT_JG; fobj->Self = fobj; fobj->LinkCount = 0; fobj->OpenFont = OpenFont; fobj->CloseFont = CloseFont; fobj->GetBitmap = GetBitmap; fobj->GetOutline = GetOutline; fobj->GetOutline2 = GetOutline2; fobj->DrawOutline = DrawOutline; fobj->FreeOutline = FreeOutline; fobj->GetCharSet = NULL; fobj->GetEnc = NULL; fobj->Link = Link; fobj->Unlink = Unlink; fobj->Locals = (long) font; return fobj; } Private int OpenFont(obj) FontObj* obj; { Font *font; font = (Font*) obj->Locals; font->PrimFont = JGOpenFont(font->FontFileName); return font->PrimFont; } Private int CloseFont(obj) FontObj *obj; { Font *font; font = (Font*) obj->Locals; return JGCloseFont(font->PrimFont); } Private int GetBitmap(obj, jiscode, w, h, bw, bo, bm_buf) FontObj *obj; int jiscode; int w; int h; int bw; int bo; char *bm_buf; { int val; long *vfdata; if ((vfdata = GetOutline(obj, jiscode)) == NULL) return -1; val = DrawOutline(obj, vfdata, w, h, bw, bo, bm_buf); FreeOutline(obj, vfdata); return val; } Private long* GetOutline(obj, jiscode) FontObj *obj; int jiscode; { Font *font; int id, x, y; long *outline, *ptr; font = (Font*) obj->Locals; id = font->PrimFont; if ((outline = JGReadOutline(2, jiscode, id)) == NULL) return NULL; outline[0] = jiscode; outline[1] = VF_SONY_COORDINATES; for (ptr = &outline[2]; *ptr != 0L; ptr++){ if ((*ptr & VFD_TOKEN) == VFD_TOKEN) continue; ConvXY(&x, &y, VFD_GET_X(*ptr), VFD_GET_Y(*ptr), font); *ptr = VFD_MAKE_XY(CONV_X(x), CONV_Y(y)); } return outline; } Private long* GetOutline2(obj, jiscode) FontObj *obj; int jiscode; { Font *font; int id, x, y; long *outline, *ptr; font = (Font*) obj->Locals; id = font->PrimFont; if ((outline = (long*) JGReadOutline(2, jiscode, id)) == NULL) return NULL; outline[0] = jiscode; outline[1] = VF_JG_COORDINATES; for (ptr = &outline[2]; *ptr != 0L; ptr++){ if ((*ptr & VFD_TOKEN) == VFD_TOKEN) continue; ConvXY(&x, &y, VFD_GET_X(*ptr), VFD_GET_Y(*ptr), font); *ptr = VFD_MAKE_XY(x, y); } return outline; } Private int DrawOutline(obj, vfdata, w, h, bw, bo, bm_buf) FontObj *obj; long *vfdata; int w; int h; int bw; int bo; char *bm_buf; { Font *font; int x, y, rast, yy1, yy2, val, frame; unsigned char *buff, d; int thin; font = (Font*) obj->Locals; rast = (w+7)/8; if ((buff = (unsigned char*) malloc(h*rast)) == NULL) return -1; /* ERR: malloc err */ bzero(buff, rast*h); switch (font->Thicken){ case 1: thin = 30; break; case 0: default: thin = 0; break; } switch (font->Frame){ case 1: frame = 1; break; case 0: default: frame = 0; break; } val = VF_Draw(vfdata, w, h, rast, buff, thin, frame); if (val < 0){ free(buff); return -1; } yy1 = 0; yy2 = 0; for (y = 0; y < h; y++){ for (x = 0; x < rast; x++){ d = buff[yy2 + x]; bm_buf[yy1 + x] |= d >> bo; bm_buf[yy1 + x+1] |= d << (8-bo); } yy1 += bw; yy2 += rast; } free(buff); return val; } Private int FreeOutline(obj, vfdata) FontObj *obj; char *vfdata; { free((char*) vfdata); return 0; } Private int Link(obj) FontObj *obj; { obj->LinkCount = obj->LinkCount + 1; return obj->LinkCount; } Private int Unlink(obj) FontObj *obj; { obj->LinkCount = obj->LinkCount - 1; return obj->LinkCount; } Private int ReadCapa(font, ent) Font *font; char *ent; { double sl; char *p; font->Thicken = 0; font->Frame = 0; font->Slant = 0; font->Rotate = 0; font->XReflect = 0; font->YReflect = 0; font->Xoffset = 0; font->Yoffset = 0; font->Xfactor = 100; font->Yfactor = 100; VFC_GetEntry(ent); if (VFC_IsDefined(VFCE_THICKEN)) font->Thicken = 1; if (VFC_IsDefined(VFCE_FRAME)) font->Frame = 1; if ((font->Slant = VFC_GetNumber(VFCE_SLANT)) == -1) font->Slant = 0; sl = font->Slant/100.0; if (sl < 0.0){ font->MatT1 = 1.0+sl; font->MatT2 = -sl; font->MatT3 = 0.0; font->MatT4 = 0.0; font->MatT5 = 1.0; font->MatT6 = 0.0; } else { font->MatT1 = 1.0-sl; font->MatT2 = -sl; font->MatT3 = sl; font->MatT4 = 0.0; font->MatT5 = 1.0; font->MatT6 = 0.0; } if ((font->Rotate = VFC_GetNumber(VFCE_ROTATE)) == -1) font->Rotate = 0; if (VFC_IsDefined(VFCE_REF_X)) font->XReflect = 1; if (VFC_IsDefined(VFCE_REF_Y)) font->YReflect = 1; if ((font->Xoffset = VFC_GetNumber(VFCE_XOFFSET)) == -1) font->Xoffset = 0; if ((font->Yoffset = VFC_GetNumber(VFCE_YOFFSET)) == -1) font->Yoffset = 0; if ((font->Xfactor = VFC_GetNumber(VFCE_XFACTOR)) == -1) font->Xfactor = 100; if ((font->Yfactor = VFC_GetNumber(VFCE_YFACTOR)) == -1) font->Yfactor = 100; font->FontFileName = NULL; if ((p = VFC_GetString(VFCE_FONT_FILE)) == NULL) return -1; if ((font->FontFileName = malloc(strlen(p)+1)) == NULL) return -1; /* ERR: malloc err */ strcpy(font->FontFileName, p); return 0; } Private void ConvXY(xp, yp, x, y, fobj) int *xp, *yp, x, y; Font *fobj; { double tmp_x, tmp_y, xfact, yfact; int xx, yy, xxx, yyy; xfact = (double)(fobj->Xfactor)/100.0; yfact = (double)(fobj->Yfactor)/100.0; tmp_x = (double) (xfact*(x-(fobj->Xoffset))); tmp_y = (double) (yfact*(y-(fobj->Yoffset))); tmp_x = (((double)tmp_x*(fobj->MatT1)) + ((double)tmp_y*(fobj->MatT2)) + ((double) JG_MAX_XY)*(fobj->MatT3)); tmp_y = (((double)tmp_x*(fobj->MatT4)) + ((double)tmp_y*(fobj->MatT5)) + ((double) JG_MAX_XY)*(fobj->MatT6)); xxx = (int) tmp_x; yyy = (int) tmp_y; switch (fobj->Rotate % 4){ default: case 0: xx = xxx; yy = yyy; break; case 1: xx = JG_MAX_XY -1 - yyy; yy = xxx; break; case 2: xx = JG_MAX_XY-1 - xxx; yy = JG_MAX_XY-1 - yyy; break; case 3: xx = yyy; yy = JG_MAX_XY-1 - xxx; break; } if (fobj->XReflect != 0) xx = JG_MAX_XY-1 - xx; if (fobj->YReflect != 0) yy = JG_MAX_XY-1 - yy; if (xx < 0) xx = 0; if (yy < 0) yy = 0; if (xx >= JG_MAX_XY) xx = JG_MAX_XY-1; if (yy >= JG_MAX_XY) yy = JG_MAX_XY-1; *xp = xx; *yp = yy; } /*** *** LOW LEVEL INTERFACE ROUTINES TO JG FONTS *** BY HIROTSUGU KAKUGAWA 1994 ***/ typedef struct { int n; int base; long *Offset; long *Size; } Header; struct prim_font { FILE_Port Fds[3]; Header *Headers[3]; int LinkCount; char *FontFileName; /* ff */ }; typedef struct prim_font PrimFont; static PrimFont PrimFontTable[VF_MAX_JG_FONTS]; #define THRESHOLD_SIZE 0x1000 /* OPEN THE FONT */ STATIC int JGOpenFont(font) char *font; { int id, i, j; char *fn; static int inited = 0; static char suff[3] = {'0', '1', '2'}; static int size[3] = {JG_CODE_SIZE0, JG_CODE_SIZE1, JG_CODE_SIZE2}; if (inited == 0){ for (id = 0; id < VF_MAX_JG_FONTS; id++){ for (i = 0; i < 3; i++){ PrimFontTable[id].Fds[i] = NULL_PORT; PrimFontTable[id].Headers[i] = NULL; } PrimFontTable[id].LinkCount = 0; PrimFontTable[id].FontFileName = NULL; } inited = 1; } for (id = 0; id < VF_MAX_JG_FONTS; id++){ /* linear search is sufficient since # of items is small */ if ((PrimFontTable[id].Fds[0] != NULL_PORT) && (strcmp(PrimFontTable[id].FontFileName, font) == 0)){ PrimFontTable[id].LinkCount++; return id; } } for (id = 0; id < VF_MAX_JG_FONTS; id++){ if (PrimFontTable[id].Fds[0] == NULL_PORT) break; } if (id == VF_MAX_JG_FONTS) return -1; /* full */ if ((PrimFontTable[id].FontFileName = malloc(strlen(font)+1)) == NULL) return -1; /* ERR: malloc err */ strcpy(PrimFontTable[id].FontFileName, font); if ((fn = malloc(strlen(font)+5)) == NULL){ free(PrimFontTable[id].FontFileName); return -1; } for (i = 0; i < 3; i++){ PrimFontTable[id].Fds[i] = NULL_PORT; PrimFontTable[id].Headers[i] = NULL; } for (i = 0; i < 3; i++){ PrimFontTable[id].Headers[i] = (Header*)malloc(sizeof(Header)); if (PrimFontTable[id].Headers[i] == NULL) goto Error; PrimFontTable[id].Headers[i]->Offset = NULL; PrimFontTable[id].Headers[i]->Size = NULL; sprintf(fn, "%s.fn%c", font, suff[i]); PrimFontTable[id].Fds[i] = VFFM_Intern(fn, NULL, NULL); if (PrimFontTable[id].Fds[i] == NULL_PORT) goto Error; /***printf(" OPEN %s\n", fn);***/ PrimFontTable[id].Headers[i]->n = size[i]; PrimFontTable[id].Headers[i]->base = 0; PrimFontTable[id].Headers[i]->Offset = (long*)malloc(size[i]*sizeof(long)); if (PrimFontTable[id].Headers[i]->Offset == NULL) goto Error; PrimFontTable[id].Headers[i]->Size = (long*)malloc(size[i]*sizeof(long)); if (PrimFontTable[id].Headers[i]->Size == NULL) goto Error; if (PrimFontTable[id].Fds[i] != NULL_PORT) JGReadHeader(PrimFontTable[id].Fds[i], PrimFontTable[id].Headers[i]); } free(fn); return id; Error: for (j = 0; j < i; j++){ if (PrimFontTable[id].Fds[j] != NULL_PORT) (void) VFFM_UnIntern(PrimFontTable[id].Fds[j]); PrimFontTable[id].Fds[j] = NULL_PORT; } free(PrimFontTable[id].FontFileName); free(fn); if (PrimFontTable[id].Headers[i] != NULL){ if (PrimFontTable[id].Headers[i]->Offset != NULL) free(PrimFontTable[id].Headers[i]->Offset); if (PrimFontTable[id].Headers[i]->Size != NULL) free(PrimFontTable[id].Headers[i]->Size); free(PrimFontTable[id].Headers[i]); } return -1; } /* CLOSE THE FONT */ STATIC int JGCloseFont(id) int id; { int i; if ((--PrimFontTable[id].LinkCount) <= 0){ for (i = 0; i < 3; i++){ if (PrimFontTable[id].Fds[i] != NULL_PORT) (void) VFFM_UnIntern(PrimFontTable[id].Fds[i]); PrimFontTable[id].Fds[i] = NULL_PORT; free(PrimFontTable[id].Headers[i]->Offset); free(PrimFontTable[id].Headers[i]->Size); free(PrimFontTable[id].Headers[i]); } free(PrimFontTable[id].FontFileName); } return PrimFontTable[id].LinkCount; } static int JGReadHeader(port, hd) FILE_Port port; Header *hd; { int prefix, i, j, CodeSize; FILE *fp; fp = VFFM_FStream(port); fseek(fp, 8L, 0); prefix = (unsigned int) Read1Byte(fp); prefix += (unsigned int) Read1Byte(fp)*0x100; /***printf(" PREFIX %04x \n", prefix); ***/ fseek(fp, (long)(prefix+0x0a), 0); hd->base = 10 + prefix + 4*hd->n; CodeSize = hd->n; for (i = 0; i < CodeSize; i++){ hd->Offset[i] = Read4Bytes(fp); /*printf(" OFFSET %04x %04x\n", i, hd->Offset[i]);*/ if (hd->Offset[i] != EMPTY_PTR) hd->Offset[i] += hd->base; } for (i = 0; i < CodeSize-1; i++){ if (hd->Offset[i] == EMPTY_PTR){ hd->Size[i] = 0; } else { /***printf(" OFFSET %04x %04x\n", i, hd->Offset[i]);***/ for (j = i+1; ; j++){ if (j >= CodeSize){ hd->Size[i] = -(THRESHOLD_SIZE+1); break; } if (hd->Offset[j] != EMPTY_PTR){ hd->Size[i] = -(hd->Offset[j] - hd->Offset[i]); break; } } } /***printf(" SIZE %04x %04x\n", i, -hd->Size[i]);***/ if (-(hd->Size[i]) > THRESHOLD_SIZE){ hd->Size[i] = EMPTY_PTR; /* CorrectSize(i, fp, hd); TOO LARGE. IS THE SIZE CORRECT? */ } } /* when i == CodeSize-1: */ if (hd->Offset[CodeSize-1] == EMPTY_PTR) hd->Size[CodeSize-1] = 0; else { hd->Size[CodeSize-1] = -(THRESHOLD_SIZE+1); CorrectSize(CodeSize-1, fp, hd); } return 0; } /* CORRECT THE SIZE OF FONT DATA */ static int CorrectSize(i, fp, hd) int i; FILE *fp; Header *hd; { int x, y; /***printf("Too Large for %04x\n Size:%04x ", i, -(hd->Size[i]));***/ Seek(fp, hd->Offset[i]); InitBitStream(fp); for (;;){ if (ReadXY(fp, &x, &y) == -1) break; while (ReadXY(fp, &x, &y) != -1) ; } hd->Size[i] = -(CurrentPos(fp) - hd->Offset[i]); /***printf("--> %04x\n", -(hd->Size[i]));***/ return hd->Size[i]; } /* GET OUTLINE DATA (IN JG COORDINATES) */ STATIC long* JGReadOutline(offset, jiscode, id) int offset, jiscode, id; { FILE_Port port; FILE *fp; int fnt_file; int token_idx, idx, cnt, cmd, x, y, cmdp, xp, yp, cmd0, x0, y0; long *outline, *sizep, size, chd; unsigned int scode, offs; scode = jis2c(jiscode); if (jiscode == 0x2121){ if ((outline = (long*) malloc((int)(1+offset)*sizeof(long))) == NULL) return NULL; outline[offset] = 0L; return outline; } if ((0x2122 <= jiscode) && (jiscode <= 0x7424)){ if (jiscode < 0x3000){ fnt_file = 0; } else if (jiscode < 0x5000){ fnt_file = 1; } else { fnt_file = 2; } } else { return NULL; } port = PrimFontTable[id].Fds[fnt_file]; fp = VFFM_FStream(port); offs = PrimFontTable[id].Headers[fnt_file]->Offset[scode]; sizep = &PrimFontTable[id].Headers[fnt_file]->Size[scode]; if (*sizep == EMPTY_PTR) CorrectSize(scode, fp, PrimFontTable[id].Headers[fnt_file]); if (*sizep == 0L) return NULL; if (*sizep < 0L) size = -3*(*sizep); /* this is enough */ else size = *sizep; if ((outline = (long*) malloc((int)(size+offset)*sizeof(long))) == NULL) return NULL; /***printf(" OUTLINE SIZE %5Ld\n", *sizep);***/ /***printf(" ALLOCATED %5Ld\n", size);***/ /***printf("=== OFFS %08x\n", offs);***/ Seek(fp, offs); InitBitStream(fp); chd = VFD_CHAR; cnt = 0; idx = offset; for (;;){ NEXT_CIRCLE: if ((cmd = ReadXY(fp, &x, &y)) == -1) break; cmd0 = cmd; x0 = x; y0 = y; cmdp = cmd; xp = x; yp = y; /***printf("CMD0=%d, X0=%d, Y0=%d\n", cmd0, CONV_X(x0), CONV_Y(y0));***/ /***printf("CMD0=%d, X0=%d, Y0=%d\n", cmd0, x0, y0);***/ token_idx = idx; outline[idx++] = (chd | VFD_CWCURV); cnt++; chd = 0L; for (;;){ cmd = ReadXY(fp, &x, &y); switch (cmd){ case -1: END_OF_CCURV: if (cmdp != cmd0){ outline[idx++] = ((cmd0==0) ? VFD_LINE : VFD_BEZ); cnt++; } outline[idx++] = VFD_MAKE_XY(xp, yp); cnt++; goto NEXT_CIRCLE; case 0: LINE: outline[token_idx] |= VFD_LINE; outline[idx++] = VFD_MAKE_XY(xp, yp); cnt++; cmdp = cmd; xp = x; yp = y; cmd = ReadXY(fp, &x, &y); while (cmd == 0){ outline[idx++] = VFD_MAKE_XY(xp, yp); cnt++; cmdp = cmd; xp = x; yp = y; cmd = ReadXY(fp, &x, &y); } if (cmd == -1) goto END_OF_CCURV; token_idx = idx; outline[idx++] = 0L; cnt++; goto BEZ; case 1: BEZ: outline[token_idx] |= VFD_BEZ; outline[idx++] = VFD_MAKE_XY(xp, yp); cnt++; cmdp = cmd; xp = x; yp = y; cmd = ReadXY(fp, &x, &y); while (cmd == 1){ outline[idx++] = VFD_MAKE_XY(xp, yp); cnt++; cmdp = cmd; xp = x; yp = y; cmd = ReadXY(fp, &x, &y); } if (cmd == -1) goto END_OF_CCURV; token_idx = idx; outline[idx++] = 0L; cnt++; goto LINE; } } } outline[idx++] = 0L; cnt++; if (*sizep < 0) *sizep = (long) cnt; /***printf(" SIZE %5Ld\n", *sizep);***/ return outline; } static int ReadXY(fp, xp, yp) FILE *fp; int *xp, *yp; { register int x, y, fx, fy; x = Read12Bits(fp); y = Read12Bits(fp); /***printf("*** %04x %04x \n", x, y);***/ if ((x == JG_MAX_VALUE) && (y == JG_MAX_VALUE)) return -1; *xp = x & JG_XY_MASK; *yp = y & JG_XY_MASK; fx = x & JG_CMD_MASK; fy = y & JG_CMD_MASK; if (*xp > (JG_MAX_XY+1)/2) *xp = (JG_MAX_XY+1) - *xp; else *xp += (JG_MAX_XY+1)/2; if (*yp < (JG_MAX_XY+1)/2) *yp = (JG_MAX_XY+1)/2 - *yp; *xp -= (JG_MAX_XY+1)/4; *xp = (*xp < 0) ? 0: *xp * 2; *yp -= (JG_MAX_XY+1)*5/16; *yp = (*yp < 0) ? 0: *yp * 2; /***printf(" %04x %04x %1x %1x\n", *xp, *yp, fx, fy);***/ if (fx != 0) return 1; return 0; } /* READ 1 BYTE INTEGER */ static int Read1Byte(fp) FILE *fp; { return fgetc(fp); } /* READ 4 BYTE INTEGER */ static unsigned long Read4Bytes(fp) FILE *fp; { unsigned long i1, i2, i3, i4; i1 = (unsigned long) Read1Byte(fp); i2 = (unsigned long) Read1Byte(fp); i3 = (unsigned long) Read1Byte(fp); i4 = (unsigned long) Read1Byte(fp); return i1 + i2*0x100 + i3*0x10000 + i4*0x1000000; } static unsigned int LeftBits = 0; static unsigned long BitStream = 0; /* INIT BIT STREAM */ static void InitBitStream(fp) FILE *fp; { BitStream = 0; LeftBits = 0; } /* READ 12 BITS INTEGER FROM BIT STREAM */ static unsigned int Read12Bits(fp) FILE *fp; { if (LeftBits < 12){ BitStream = BitStream * 0x10000L; BitStream += (unsigned int) Read1Byte(fp); BitStream += (unsigned int) Read1Byte(fp) * 0x0100L; LeftBits += 16; } LeftBits -= 12; return (BitStream >> LeftBits) & JG_MAX_VALUE; } /* SEEK TO THE OFFSET */ static void Seek(fp, offset) FILE *fp; long offset; { fseek(fp, offset, 0); } /* RETURN CURRENT OFFSET FOR FONT DATA */ static long CurrentPos(fp) FILE *fp; { return ftell(fp); } static int jis2c(code) int code; { int jgcode; if (code < 0x3000) jgcode = (((code>>8)&0xff) - 0x21)*0x5e + (code&0xff) - 0x21; else if (code < 0x5000) jgcode = (((code>>8)&0xff) - 0x30)*0x5e + (code&0xff) - 0x21; else jgcode = (((code>>8)&0xff) - 0x50)*0x5e + (code&0xff) - 0x21; return jgcode; } /* EOF */