/* * Win3.1J EUDC fontfile i/o ( MS-Code base) * * Copyright (c) 1997-1999 Microsoft Corporation. */ #include "stdafx.h" #pragma pack(2) #include "extfunc.h" /* File Structure */ struct W31_Header { char identify[72]; short segCnt; /* ??? */ unsigned short sCode, eCode; short cCnt; long ofsCmap; short sizCmap; long ofsFil; short sizFil; long ofsStbl; /* search tbl*/ short sizStbl; long ofsBdatSub; }; struct BDatSubTbl { long tail; long ptrOfs; long head; short filler2; /* Following Pointer tbl. */ }; struct BMPHeader { long bitmapSiz; short xsiz, ysiz; }; #define EUDCCODEBASE ((unsigned short)0xe000) int OpenW31JBMP(TCHAR *path,int omd); int CloseW31JBMP(void); int isW31JEUDCBMP(TCHAR *path); int GetW31JBMPnRecs(int *nRec, int *nGlyph, int *xsiz, int *ysiz); int GetW31JBMPMeshSize( int *xsiz, int *ysiz); static int readcmap(void); static int rectocode(int rec,unsigned short *code); static int searchCode(unsigned short code); int GetW31JBMP(unsigned short code,LPBYTE buf,int bufsiz,int *xsiz,int *ysiz); int GetW31JBMPRec(int rec,LPBYTE buf,int bufsiz,int *xsiz,int *ysiz,unsigned short *code); int PutW31JBMPRec(int rec,LPBYTE buf,int xsiz,int ysiz); static int ReadBMPHdr(HANDLE hdl,long ofs,struct BMPHeader *bhdr); static int WriteBMPHdr(HANDLE hdl,long ofs,struct BMPHeader *bhdr); static int init = 0; static HANDLE fHdl; struct W31_Header hdr; struct BDatSubTbl bdTbl; static int rwmode = 0; static long *ofstbl=0; static unsigned short *cmap=0; static int *recordTbl=0; /*************************************************************** * Initialize */ /* */ int /* */ OpenW31JBMP( TCHAR *path, int omd) /* * returns : 0, -1 ***************************************************************/ { int msiz; DWORD nByte; BOOL res; /* open EUDC Font File */ rwmode = omd ? 1 : 0; fHdl = CreateFile(path, omd==0 ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if ( fHdl == INVALID_HANDLE_VALUE) return -1; /* Read Header */ res = ReadFile( fHdl, (LPBYTE)&hdr, sizeof(struct W31_Header), &nByte, NULL); if (!res || nByte !=sizeof(struct W31_Header)) goto ERET; // // WinSE #13986, // In Win9x, character number could be well over 1880, // EUDC EUF file will be trashed if we limit character number to 1880 // /* if( hdr.cCnt > 1880) hdr.cCnt = 1880; */ /* allocate ofs. tbl. */ msiz = hdr.cCnt*sizeof(long); if ((ofstbl = (long *)malloc( msiz))==(long *)0) goto ERET; /* Read Ofs. tbl.*/ if ( (long) SetFilePointer( fHdl, hdr.ofsBdatSub, NULL, FILE_BEGIN)!=hdr.ofsBdatSub) goto ERET; res = ReadFile( fHdl, (LPBYTE)&bdTbl, sizeof(bdTbl), &nByte, NULL); if (!res || nByte !=sizeof(bdTbl)) goto ERET; res = ReadFile( fHdl, (LPBYTE)ofstbl, (unsigned int)msiz, &nByte, NULL); if (!res || nByte !=(unsigned int)msiz) goto ERET; init = 1; /* if (fHdl != INVALID_HANDLE_VALUE) { CloseHandle(fHdl); fHdl = INVALID_HANDLE_VALUE; } */ return 0; ERET: if (fHdl != INVALID_HANDLE_VALUE) { CloseHandle (fHdl); fHdl = INVALID_HANDLE_VALUE; } if (ofstbl) { free( ofstbl); ofstbl = 0; } return -1; } /*************************************************************** * Terminate Close */ /* */ int /* */ CloseW31JBMP() /* * returns : none ***************************************************************/ { unsigned int siz; DWORD nByte; BOOL res; if ( rwmode>=1) { /* update ofstbl*/ if ((long) SetFilePointer( fHdl, hdr.ofsBdatSub, NULL, FILE_BEGIN)!=hdr.ofsBdatSub) goto ERET; res = WriteFile( fHdl, (LPBYTE)&bdTbl, sizeof( bdTbl), &nByte, NULL); if (!res || nByte !=sizeof(bdTbl)) goto ERET; siz = (unsigned int)hdr.cCnt*sizeof(long); res = WriteFile( fHdl, (LPBYTE)ofstbl, siz, &nByte, NULL); if (!res || nByte !=siz) goto ERET; } if ( fHdl !=INVALID_HANDLE_VALUE) { CloseHandle( fHdl); fHdl = INVALID_HANDLE_VALUE; } if ( ofstbl) { free(ofstbl); ofstbl = 0; } if ( cmap) { free(cmap); cmap = 0; } if ( recordTbl) { free(recordTbl); recordTbl = 0; } init = 0; return 0; ERET: return -1; } /*************************************************************** * is Win3.1J EUDC bitmap */ /* */ int /* */ isW31JEUDCBMP( TCHAR *path) /* * returns : 0 (other), 1 (EUDC bitmap), -1(error) ***************************************************************/ { HANDLE fhdl; struct W31_Header hdr; DWORD nByte; BOOL res; fhdl = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if ( fhdl == INVALID_HANDLE_VALUE) return -1; res = ReadFile( fhdl, (LPBYTE)&hdr, sizeof(hdr), &nByte, NULL); if (!res || nByte !=sizeof(hdr)) goto NO_WIN31J; CloseHandle( fhdl); fhdl = INVALID_HANDLE_VALUE; /* compare idendify leading 16 byte, sCode, eCode and cCnt*/ if (memcmp( hdr.identify, "WINEUDC2Standard", 16)) goto NO_WIN31J; #if 0 if ( hdr.sCode != 0x40f0 || hdr.eCode != 0xfcf9 || hdr.cCnt != 1880) #endif if( hdr.sCode != 0x40f0) goto NO_WIN31J; return 1; NO_WIN31J: if (fhdl != INVALID_HANDLE_VALUE) { CloseHandle(fhdl); fhdl = INVALID_HANDLE_VALUE; } return 0; } /*************************************************************** * Get number of records */ /* */ int /* */ GetW31JBMPnRecs( int *nRec, int *nGlyph, int *xsiz, int *ysiz) /* * returns : 0, -1 ***************************************************************/ { struct BMPHeader fhdr; long ofs; BOOL bFirst; int rec; int gc; DWORD nByte; BOOL res; bFirst = FALSE; if ( init==0 || fHdl == INVALID_HANDLE_VALUE) return -1; else { gc = 0; for ( rec = 0; rec < (int)hdr.cCnt; rec++) { if( *(ofstbl+rec)){ if( !bFirst){ ofs = *(ofstbl+rec); ofs += hdr.ofsBdatSub; if ( (DWORD) SetFilePointer( fHdl,ofs, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { DWORD dwErr = GetLastError(); goto ERET; } res = ReadFile( fHdl, (LPBYTE)&fhdr, sizeof(struct BMPHeader), &nByte, NULL); if (!res || nByte != sizeof( struct BMPHeader)) goto ERET; bFirst = TRUE; } gc++; } } *nRec = (int)hdr.cCnt; *nGlyph = gc; *xsiz = fhdr.xsiz; *ysiz = fhdr.ysiz; return 0; } ERET: return( -1); } static int readcmap() { unsigned int msiz; DWORD nByte; BOOL res; msiz = (unsigned int)hdr.cCnt*sizeof(unsigned short); if ((cmap = (unsigned short*)malloc(msiz))==(unsigned short *)0) goto ERET; if ((long) SetFilePointer( fHdl, hdr.ofsCmap, NULL, FILE_BEGIN)!=hdr.ofsCmap) goto ERET; res = ReadFile( fHdl, (LPBYTE)cmap, msiz, &nByte, NULL); if (!res || nByte !=msiz) goto ERET; return 0; ERET: return -1; } static int rectocode( int rec, unsigned short *code) { if ( cmap==0) { if (readcmap()) return -1; } *code = *(cmap+rec); return 0; } static int searchCode( unsigned short code) { int high, low, mid; if ( cmap==(unsigned short *)0) { if (readcmap()) goto ERET; } high = hdr.cCnt-1; low = 0; while ( high >= low) { mid = (high+low)/2; if ( *(cmap+mid)==code) return mid; else if ( *(cmap+mid)>code) high = mid-1; else low = mid+1; } ERET: return -1; } /*************************************************************** * Read Bitmap by code number */ /* */ int /* */ GetW31JBMP( /* */ unsigned short code, /* code Number */ /* */ LPBYTE buf, /* buffer to set bitmap */ /* */ int bufsiz, /* Buffer Size */ /* */ int *xsiz, /* Bitmap X,Ysiz */ /* */ int *ysiz) /* * returns : >=0, -1 ***************************************************************/ { int rec; int sts; unsigned short rcode; /* search code */ if ( (rec = searchCode( code)) <0) return -1; else { sts = GetW31JBMPRec( rec, buf, bufsiz, xsiz, ysiz, &rcode); return sts; } } /****************************************/ /* */ /* Get W31JEUDC's Bmp Mesh Size */ /* */ /****************************************/ int GetW31JBMPMeshSize( int *xsiz, int *ysiz) { long ofs; struct BMPHeader fhdr; int bmpsiz; DWORD nByte; BOOL res; if (init==0) return -1; ofs = *(ofstbl); if ( ofs==0L) return 0; ofs += hdr.ofsBdatSub; if ( (long) SetFilePointer(fHdl, ofs, NULL, FILE_BEGIN)!=ofs) goto ERET; res = ReadFile( fHdl, (LPBYTE)&fhdr, sizeof(struct BMPHeader), &nByte, NULL); if (!res || nByte != sizeof( struct BMPHeader)) goto ERET; *xsiz = fhdr.xsiz; *ysiz = fhdr.ysiz; bmpsiz = ((int)fhdr.xsiz+15)/16 *2 * (int)fhdr.ysiz; return bmpsiz; ERET: return (-1); } /*************************************************************** * Read Bitmap by record number */ /* */ int /* */ GetW31JBMPRec( /* */ int rec, /* Record Number */ /* */ LPBYTE buf, /* buffer to set bitmap */ /* */ int bufsiz, /* Buffer Size */ /* */ int *xsiz, /* Bitmap X,Ysiz */ /* */ int *ysiz, /* */ unsigned short *code) /* * returns : bitmapsiz >=0, -1 ***************************************************************/ { long ofs; struct BMPHeader fhdr; int bmpsiz; int rdsiz; DWORD nByte; BOOL res; if (init==0) return -1; ofs = *(ofstbl+rec); if ( ofs==0L) return 0; ofs += hdr.ofsBdatSub; /* read Bitmap Header bitmap is Word aligned */ if ( (long) SetFilePointer( fHdl, ofs, NULL, FILE_BEGIN)!=ofs) goto ERET; res = ReadFile( fHdl, (LPBYTE)&fhdr, sizeof(struct BMPHeader), &nByte, NULL); if (!res || nByte != sizeof( struct BMPHeader)) goto ERET; bmpsiz = ((int)fhdr.xsiz+15)/16 *2 * (int)fhdr.ysiz; /* Read Bitmap Body */ rdsiz = bmpsiz > bufsiz ? bufsiz : bmpsiz; if ( rdsiz > 0) { res = ReadFile( fHdl, buf, (unsigned int)rdsiz, &nByte, NULL); if (!res || nByte !=(unsigned int)rdsiz) goto ERET; } *xsiz = fhdr.xsiz; *ysiz = fhdr.ysiz; if ( rectocode( rec, code)) goto ERET; return bmpsiz; ERET: return -1; } /*************************************************************** * Write Bitmap by record number */ /* */ int /* */ PutW31JBMPRec( /* */ int rec, /* Record Number */ /* */ LPBYTE buf, /* buffer to set bitmap */ /* */ int xsiz, /* Bitmap X,Ysiz */ /* */ int ysiz) /* * returns : 0, -1 ***************************************************************/ { long ofs; struct BMPHeader fhdr; int bmpsiz; unsigned int wbmpsiz; DWORD nByte; BOOL res; if (init==0) return -1; else if ( rwmode==0) return -1; rwmode = 2; wbmpsiz = (unsigned int) ((xsiz+15)/16 *2 * ysiz); ofs = *(ofstbl+rec); if ( ofs != 0L) { /* read Bitmap Header bitmap is Word aligned */ if ( ReadBMPHdr( fHdl, ofs, &fhdr)) goto ERET; bmpsiz = ((int)fhdr.xsiz+15)/16 *2 * (int)fhdr.ysiz; if ( bmpsiz<(int)wbmpsiz) ofs = 0L; } if ( ofs == 0L) ofs = bdTbl.tail; /* Write Bitmap Header */ fhdr.xsiz = (short)xsiz; fhdr.ysiz = (short)ysiz; fhdr.bitmapSiz = wbmpsiz+sizeof(fhdr); if ( WriteBMPHdr( fHdl, ofs, &fhdr)) goto ERET; /* Write Bitmap Body */ res = WriteFile( fHdl, buf, wbmpsiz, &nByte, NULL); if (!res || nByte !=wbmpsiz) goto ERET; /* write bitmap ptr on subTable */ *(ofstbl+rec) = ofs; bdTbl.tail = ofs + wbmpsiz+sizeof(fhdr); return 0; ERET: return -1; } static int ReadBMPHdr( HANDLE hdl, long ofs, struct BMPHeader *bhdr) { DWORD nByte; BOOL res; ofs += hdr.ofsBdatSub; if ( (long) SetFilePointer( hdl, ofs, NULL, FILE_BEGIN)!=ofs) goto ERET; res = ReadFile( hdl, (LPBYTE) bhdr, sizeof( struct BMPHeader), &nByte, NULL); if (!res || nByte !=sizeof( struct BMPHeader)) goto ERET; return 0; ERET: return -1; } static int WriteBMPHdr( HANDLE hdl, long ofs, struct BMPHeader *bhdr) { DWORD nByte; BOOL res; ofs += hdr.ofsBdatSub; if ( (long) SetFilePointer( hdl, ofs, NULL, FILE_BEGIN)!=ofs) goto ERET; res = WriteFile(hdl, (LPBYTE )bhdr, sizeof( struct BMPHeader), &nByte, NULL); if (!res || nByte !=sizeof( struct BMPHeader)) goto ERET; return 0; ERET: return -1; } int W31JrecTbl( int **recTbl, BOOL bIsWin95EUDC) { int rec; int *tp; unsigned short code; if ( cmap==0) { if (readcmap()) return -1; } if ( (tp = (int *)malloc( sizeof(int)*hdr.cCnt))==(int *)0) return -1; for ( rec = 0; rec < hdr.cCnt; rec++) { if ( *(ofstbl + rec)!=0L) { code = *(cmap+rec); if (!bIsWin95EUDC) code = sjisToUniEUDC( code); tp[(int)(code - EUDCCODEBASE)] = rec; } else tp[rec] = -1; } *recTbl = recordTbl = tp; return 0; } /* EOF */