/* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */ // // Copyright (c) 2009, Wei Mingzhi . // All rights reserved. // // This file is part of SDLPAL. // // SDLPAL 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 3 of the License, 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. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // Modified by Lou Yihua with Unicode support, 2015 // #include "font.h" #include "util.h" #if defined(PAL_UNICODE) #include "fontglyph.h" INT PAL_InitFont( VOID ) /*++ Purpose: Load the font files. Parameters: None. Return value: 0 if succeed. --*/ { return 0; } VOID PAL_FreeFont( VOID ) /*++ Purpose: Free the memory used for fonts. Parameters: None. Return value: None. --*/ { } VOID PAL_DrawCharOnSurface( WORD wChar, SDL_Surface *lpSurface, PAL_POS pos, BYTE bColor ) /*++ Purpose: Draw a Unicode character on a surface. Parameters: [IN] wChar - the unicode character to be drawn. [OUT] lpSurface - the destination surface. [IN] pos - the destination location of the surface. [IN] bColor - the color of the character. Return value: None. --*/ { int i, j; int x = PAL_X(pos), y = PAL_Y(pos); // // Check for NULL pointer & invalid char code. // if (lpSurface == NULL || (wChar >= 0xd800 && wChar < unicode_upper_base) || wChar >= unicode_upper_top) { return; } // // Locate for this character in the font lib. // if (wChar >= unicode_upper_base) { wChar -= (unicode_upper_base - 0xd800); } // // Draw the character to the surface. // LPBYTE dest = (LPBYTE)lpSurface->pixels + y * lpSurface->pitch + x; if (font_width[wChar] == 32) { for (i = 0; i < 32; i += 2, dest += lpSurface->pitch) { for (j = 0; j < 8; j++) { if (unicode_font[wChar][i] & (1 << (7 - j))) { dest[j] = bColor; } } for (j = 0; j < 8; j++) { if (unicode_font[wChar][i + 1] & (1 << (7 - j))) { dest[j + 8] = bColor; } } } } else { for (i = 0; i < 16; i++, dest += lpSurface->pitch) { for (j = 0; j < 8; j++) { if (unicode_font[wChar][i] & (1 << (7 - j))) { dest[j] = bColor; } } } } } INT PAL_CharWidth( WORD wChar ) { if ((wChar >= 0xd800 && wChar < unicode_upper_base) || wChar >= unicode_upper_top) { return 0; } // // Locate for this character in the font lib. // if (wChar >= unicode_upper_base) { wChar -= (unicode_upper_base - 0xd800); } return font_width[wChar] >> 1; } #elif defined(PAL_WIN95) /* * Portions based on: * * YH - Console Chinese Environment - * Copyright (C) 1999 Red Flag Linux (office@sonata.iscas.ac.cn) * * 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 RED FLAG LINUX ``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 TERRENCE R. LAMBERT 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. * */ /* * Portions based on: * * KON2 - Kanji ON Console - * Copyright (C) 1992-1996 Takashi MANABE (manabe@papilio.tutics.tut.ac.jp) * * CCE - Console Chinese Environment - * Copyright (C) 1998-1999 Rui He (herui@cs.duke.edu) * * 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 TAKASHI MANABE ``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 TERRENCE R. LAMBERT 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 "gbfont.h" #include "big5font.h" BOOL fIsBig5 = FALSE; INT PAL_InitFont( VOID ) /*++ Purpose: Load the font files. Parameters: None. Return value: 0 if succeed, -1 if cannot allocate memory, -2 if cannot load files. --*/ { FILE *fp; fp = fopen(PAL_PREFIX "word.dat", "rb"); if (!fp) { return 0; } fseek(fp, 0x1E, SEEK_SET); if (fgetc(fp) == 0xAA) { fIsBig5 = TRUE; } fclose(fp); return 0; } VOID PAL_FreeFont( VOID ) /*++ Purpose: Free the memory used for fonts. Parameters: None. Return value: None. --*/ { } static BOOL is_gb(unsigned char b1, unsigned char b2) { if (b1 < 0xa1 || b1 > 0xfe) return FALSE; if (b2 < 0xa1 || b2 > 0xfe) return FALSE; return TRUE; } VOID PAL_DrawCharOnSurface( WORD wChar, SDL_Surface *lpSurface, PAL_POS pos, BYTE bColor ) /*++ Purpose: Draw a BIG-5 Chinese character on a surface. Parameters: [IN] wChar - the character to be drawn (in GB2312/BIG5). [OUT] lpSurface - the destination surface. [IN] pos - the destination location of the surface. [IN] bColor - the color of the character. Return value: None. --*/ { int i, j, dx; int x = PAL_X(pos), y = PAL_Y(pos); LPBYTE pChar; BYTE ch1, ch2; // // Check for NULL pointer. // if (lpSurface == NULL) { return; } // // Locate for this character in the font lib. // ch1 = wChar & 0xff; ch2 = wChar >> 8; if (fIsBig5) { if (ch2 < 0xa1) pChar = &big5font[((ch1 - 0xA1) * 157 + ch2 - 0x40) << 5] + 8; else pChar = &big5font[((ch1 - 0xA1) * 157 + 63 + ch2 - 0xA1) << 5] + 8; } else { if (!is_gb(ch1, ch2)) { return; } pChar = &gbfont[((ch1 - 0xa1) * 94 + (ch2 - 0xa1)) * 32]; } if (pChar == NULL) return; // // Draw the character to the surface. // if (y >= lpSurface->h) return; y *= lpSurface->pitch; for (i = 0; i < 32; i++) { dx = x + ((i & 1) << 3); for (j = 0; j < 8; j++) { if (pChar[i] & (1 << (7 - j))) { if (dx < lpSurface->w) { ((LPBYTE)(lpSurface->pixels))[y + dx] = bColor; } else { break; } } dx++; } y += (i & 1) * lpSurface->pitch; if (y / lpSurface->pitch >= lpSurface->h) { break; } } } VOID PAL_DrawASCIICharOnSurface( BYTE bChar, SDL_Surface *lpSurface, PAL_POS pos, BYTE bColor ) /*++ Purpose: Draw a ASCII character on a surface. Parameters: [IN] bChar - the character to be drawn. [OUT] lpSurface - the destination surface. [IN] pos - the destination location of the surface. [IN] bColor - the color of the character. Return value: None. --*/ { int i, j, dx; int x = PAL_X(pos), y = PAL_Y(pos); LPBYTE pChar; pChar = &iso_font[(int)(bChar & ~128) * 15]; // // Check for NULL pointer. // if (lpSurface == NULL) { return; } // // Draw the character to the surface. // if (y >= lpSurface->h) return; y *= lpSurface->pitch; for (i = 0; i < 15; i++) { dx = x; for (j = 0; j < 8; j++) { if (pChar[i] & (1 << j)) { if (dx < lpSurface->w) { ((LPBYTE)(lpSurface->pixels))[y + dx] = bColor; } else { break; } } dx++; } y += lpSurface->pitch; if (y / lpSurface->pitch >= lpSurface->h) { break; } } } #else typedef struct tagFont { LPWORD lpBufChar; LPBYTE lpBufGlyph; INT nChar; } FONT, *LPFONT; static LPFONT gpFont = NULL; INT PAL_InitFont( VOID ) /*++ Purpose: Load the font files. Parameters: None. Return value: 0 if succeed, -1 if cannot allocate memory, -2 if cannot load files. --*/ { FILE *fp; if (gpFont != NULL) { // // Already initialized // return 0; } gpFont = (LPFONT)calloc(1, sizeof(FONT)); if (gpFont == NULL) { return -1; } // // Load the wor16.asc file. // fp = UTIL_OpenRequiredFile("wor16.asc"); // // Get the size of wor16.asc file. // fseek(fp, 0, SEEK_END); gpFont->nChar = ftell(fp); gpFont->nChar /= 2; // // Read all the character codes. // gpFont->lpBufChar = (LPWORD)calloc(gpFont->nChar, sizeof(WORD)); if (gpFont->lpBufChar == NULL) { free(gpFont); gpFont = NULL; return -1; } fseek(fp, 0, SEEK_SET); fread(gpFont->lpBufChar, sizeof(WORD), gpFont->nChar, fp); // // Close wor16.asc file. // fclose(fp); // // Read all bitmaps from wor16.fon file. // fp = UTIL_OpenRequiredFile("wor16.fon"); gpFont->lpBufGlyph = (LPBYTE)calloc(gpFont->nChar, 30); if (gpFont->lpBufGlyph == NULL) { free(gpFont->lpBufChar); free(gpFont); gpFont = NULL; return -1; } // // The font glyph data begins at offset 0x682 in wor16.fon. // fseek(fp, 0x682, SEEK_SET); fread(gpFont->lpBufGlyph, 30, gpFont->nChar, fp); fclose(fp); return 0; } VOID PAL_FreeFont( VOID ) /*++ Purpose: Free the memory used for fonts. Parameters: None. Return value: None. --*/ { if (gpFont != NULL) { free(gpFont->lpBufChar); free(gpFont->lpBufGlyph); free(gpFont); } gpFont = NULL; } VOID PAL_DrawCharOnSurface( WORD wChar, SDL_Surface *lpSurface, PAL_POS pos, BYTE bColor ) /*++ Purpose: Draw a BIG-5 Chinese character on a surface. Parameters: [IN] wChar - the character to be drawn (in BIG-5). [OUT] lpSurface - the destination surface. [IN] pos - the destination location of the surface. [IN] bColor - the color of the character. Return value: None. --*/ { int i, j, dx; int x = PAL_X(pos), y = PAL_Y(pos); LPBYTE pChar; // // Check for NULL pointer. // if (lpSurface == NULL || gpFont == NULL) { return; } // // Locate for this character in the font lib. // for (i = 0; i < gpFont->nChar; i++) { if (gpFont->lpBufChar[i] == wChar) { break; } } if (i >= gpFont->nChar) { // // This character does not exist in the font lib. // return; } pChar = gpFont->lpBufGlyph + i * 30; // // Draw the character to the surface. // y *= lpSurface->pitch; for (i = 0; i < 30; i++) { dx = x + ((i & 1) << 3); for (j = 0; j < 8; j++) { if (pChar[i] & (1 << (7 - j))) { ((LPBYTE)(lpSurface->pixels))[y + dx] = bColor; } dx++; } y += (i & 1) * lpSurface->pitch; } } VOID PAL_DrawASCIICharOnSurface( BYTE bChar, SDL_Surface *lpSurface, PAL_POS pos, BYTE bColor ) /*++ Purpose: Draw a ASCII character on a surface. Parameters: [IN] bChar - the character to be drawn. [OUT] lpSurface - the destination surface. [IN] pos - the destination location of the surface. [IN] bColor - the color of the character. Return value: None. --*/ { int i, j, dx; int x = PAL_X(pos), y = PAL_Y(pos); LPBYTE pChar = &iso_font[(int)(bChar & ~128) * 15]; // // Check for NULL pointer. // if (lpSurface == NULL) { return; } // // Draw the character to the surface. // y *= lpSurface->pitch; for (i = 0; i < 15; i++) { dx = x; for (j = 0; j < 8; j++) { if (pChar[i] & (1 << j)) { ((LPBYTE)(lpSurface->pixels))[y + dx] = bColor; } dx++; } y += lpSurface->pitch; } } #endif