/* -*- 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" #define _FONT_C #if defined(PAL_UNICODE) #include "fontglyph.h" INT PAL_InitFont( VOID ) /*++ Purpose: None. Parameters: None. Return value: Always return 0. --*/ { return 0; } VOID PAL_FreeFont( VOID ) /*++ Purpose: None. 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; LPBYTE top = (LPBYTE)lpSurface->pixels + lpSurface->h * lpSurface->pitch; if (font_width[wChar] == 32) { for (i = 0; i < 32 && dest < top; i += 2, dest += lpSurface->pitch) { for (j = 0; j < 8 && x + j < lpSurface->w; j++) { if (unicode_font[wChar][i] & (1 << (7 - j))) { dest[j] = bColor; } } for (j = 0; j < 8 && x + j + 8 < lpSurface->w; j++) { if (unicode_font[wChar][i + 1] & (1 << (7 - j))) { dest[j + 8] = bColor; } } } } else { for (i = 0; i < 16 && dest < top; i++, dest += lpSurface->pitch) { for (j = 0; j < 8 && x + j < lpSurface->w; j++) { if (unicode_font[wChar][i] & (1 << (7 - j))) { dest[j] = bColor; } } } } } INT PAL_CharWidth( WORD wChar ) /*++ Purpose: Get the text width of a character. Parameters: [IN] wChar - the unicode character for width calculation. Return value: The width of the character, 16 for full-width char and 8 for half-width char. --*/ { 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; } #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