Add the ability to print unicode characters in addition to "Latin1" ones
This commit is contained in:
parent
b564a4d4f4
commit
545308265b
BIN
share/grafx2/skins/unicode_0410-044F.png
Normal file
BIN
share/grafx2/skins/unicode_0410-044F.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@ -1459,7 +1459,7 @@ void Button_Skins(void)
|
|||||||
T_Fileselector_item* fontName;
|
T_Fileselector_item* fontName;
|
||||||
selected_font = Window_attribute2; // Get the index of the chosen font.
|
selected_font = Window_attribute2; // Get the index of the chosen font.
|
||||||
fontName = Get_item_by_index(&Font_files_list,selected_font);
|
fontName = Get_item_by_index(&Font_files_list,selected_font);
|
||||||
new_font = Load_font(fontName->Full_name);
|
new_font = Load_font(fontName->Full_name, 1);
|
||||||
if (new_font)
|
if (new_font)
|
||||||
{
|
{
|
||||||
free(Menu_font);
|
free(Menu_font);
|
||||||
@ -1498,7 +1498,7 @@ void Button_Skins(void)
|
|||||||
Set_current_skin(skinsdir, gfx);
|
Set_current_skin(skinsdir, gfx);
|
||||||
}
|
}
|
||||||
// (Re-)load the selected font
|
// (Re-)load the selected font
|
||||||
new_font = Load_font(Get_item_by_index(&Font_files_list,selected_font)->Full_name);
|
new_font = Load_font(Get_item_by_index(&Font_files_list,selected_font)->Full_name, 1);
|
||||||
if (new_font)
|
if (new_font)
|
||||||
{
|
{
|
||||||
const char * fname;
|
const char * fname;
|
||||||
|
|||||||
@ -646,6 +646,9 @@ GFX2_GLOBAL byte Resolution_in_command_line;
|
|||||||
/// Pointer to the font selected for menus.
|
/// Pointer to the font selected for menus.
|
||||||
GFX2_GLOBAL byte * Menu_font;
|
GFX2_GLOBAL byte * Menu_font;
|
||||||
|
|
||||||
|
/// additional fonts for unicode characters
|
||||||
|
GFX2_GLOBAL T_Unicode_Font * Unicode_fonts;
|
||||||
|
|
||||||
/// Pointer to the current active skin.
|
/// Pointer to the current active skin.
|
||||||
GFX2_GLOBAL T_Gui_skin * Gfx;
|
GFX2_GLOBAL T_Gui_skin * Gfx;
|
||||||
|
|
||||||
|
|||||||
71
src/init.c
71
src/init.c
@ -701,27 +701,36 @@ T_Gui_skin * Load_graphics(const char * skin_file, T_Gradient_array *gradients)
|
|||||||
|
|
||||||
// ---- font loading -----
|
// ---- font loading -----
|
||||||
|
|
||||||
byte Parse_font(SDL_Surface * image, byte * font)
|
static byte * Parse_font(SDL_Surface * image, int is_main)
|
||||||
{
|
{
|
||||||
|
byte * font;
|
||||||
int character;
|
int character;
|
||||||
byte color;
|
byte color;
|
||||||
int x, y;
|
int x, y;
|
||||||
int chars_per_line;
|
int chars_per_line;
|
||||||
|
int character_count;
|
||||||
|
|
||||||
// Check image size
|
// Check image size
|
||||||
if (image->w % 8)
|
if (image->w % 8)
|
||||||
{
|
{
|
||||||
sprintf(Gui_loading_error_message, "Error in font file: Image width is not a multiple of 8.\n");
|
sprintf(Gui_loading_error_message, "Error in font file: Image width is not a multiple of 8.\n");
|
||||||
return 1;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (image->w * image->h < 8*8*256)
|
character_count = (image->w * image->h) / (8*8);
|
||||||
|
if (is_main && character_count < 256)
|
||||||
{
|
{
|
||||||
sprintf(Gui_loading_error_message, "Error in font file: Image is too small to be a 256-character 8x8 font.\n");
|
sprintf(Gui_loading_error_message, "Error in font file: Image is too small to be a 256-character 8x8 font.\n");
|
||||||
return 1;
|
return NULL;
|
||||||
|
}
|
||||||
|
font = (byte *)malloc(8*8*character_count);
|
||||||
|
if (font == NULL)
|
||||||
|
{
|
||||||
|
sprintf(Gui_loading_error_message, "Not enough memory to read font file\n");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
chars_per_line = image->w/8;
|
chars_per_line = image->w/8;
|
||||||
|
|
||||||
for (character=0; character < 256; character++)
|
for (character=0; character < character_count; character++)
|
||||||
{
|
{
|
||||||
for (y=0; y<8; y++)
|
for (y=0; y<8; y++)
|
||||||
{
|
{
|
||||||
@ -732,19 +741,20 @@ byte Parse_font(SDL_Surface * image, byte * font)
|
|||||||
if (color > 1)
|
if (color > 1)
|
||||||
{
|
{
|
||||||
sprintf(Gui_loading_error_message, "Error in font file: Only colors 0 and 1 can be used for the font.\n");
|
sprintf(Gui_loading_error_message, "Error in font file: Only colors 0 and 1 can be used for the font.\n");
|
||||||
return 1;
|
free(font);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
// Put it in font. 0 = BG, 1 = FG.
|
// Put it in font. 0 = BG, 1 = FG.
|
||||||
font[character*64 + y*8 + x]=color;
|
font[character*64 + y*8 + x]=color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte * Load_font(const char * font_name)
|
byte * Load_font(const char * font_name, int is_main)
|
||||||
{
|
{
|
||||||
byte * font;
|
byte * font = NULL;
|
||||||
char filename[MAX_PATH_CHARACTERS];
|
char filename[MAX_PATH_CHARACTERS];
|
||||||
SDL_Surface * image;
|
SDL_Surface * image;
|
||||||
|
|
||||||
@ -754,13 +764,6 @@ byte * Load_font(const char * font_name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
font = (byte *)malloc(8*8*256);
|
|
||||||
if (font == NULL)
|
|
||||||
{
|
|
||||||
sprintf(Gui_loading_error_message, "Not enough memory to read font file\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the file containing the image
|
// Read the file containing the image
|
||||||
sprintf(filename,"%s" SKINS_SUBDIRECTORY "%s%s", Data_directory, PATH_SEPARATOR, font_name);
|
sprintf(filename,"%s" SKINS_SUBDIRECTORY "%s%s", Data_directory, PATH_SEPARATOR, font_name);
|
||||||
|
|
||||||
@ -768,19 +771,41 @@ byte * Load_font(const char * font_name)
|
|||||||
if (!image)
|
if (!image)
|
||||||
{
|
{
|
||||||
sprintf(Gui_loading_error_message, "Unable to load the skin image (missing? not an image file?)\n");
|
sprintf(Gui_loading_error_message, "Unable to load the skin image (missing? not an image file?)\n");
|
||||||
free(font);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (Parse_font(image, font))
|
|
||||||
{
|
|
||||||
SDL_FreeSurface(image);
|
|
||||||
free(font);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
font = Parse_font(image, is_main);
|
||||||
SDL_FreeSurface(image);
|
SDL_FreeSurface(image);
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Load_Unicode_font(const char * filename)
|
||||||
|
{
|
||||||
|
T_Unicode_Font * ufont;
|
||||||
|
byte * font;
|
||||||
|
unsigned int first, last;
|
||||||
|
|
||||||
|
if (sscanf(filename, "unicode_%04X-%04X.png", &first, &last) == 2)
|
||||||
|
{
|
||||||
|
font = Load_font(filename, 0);
|
||||||
|
if (font)
|
||||||
|
{
|
||||||
|
ufont = malloc(sizeof(T_Unicode_Font));
|
||||||
|
ufont->FirstChar = first;
|
||||||
|
ufont->LastChar = last;
|
||||||
|
ufont->FontData = font;
|
||||||
|
ufont->Next = Unicode_fonts;
|
||||||
|
Unicode_fonts = ufont;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Warning("Could not parse filename");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Load_Unicode_fonts(void)
|
||||||
|
{
|
||||||
|
// TODO : for each unicode*.png file in skin directory
|
||||||
|
Load_Unicode_font("unicode_0410-044F.png");
|
||||||
|
}
|
||||||
|
|
||||||
// Initialisation des boutons:
|
// Initialisation des boutons:
|
||||||
|
|
||||||
|
|||||||
@ -47,4 +47,7 @@ extern char Gui_loading_error_message[512];
|
|||||||
/// successful.
|
/// successful.
|
||||||
/// If an error is encountered, it frees what needs it, prints an error message
|
/// If an error is encountered, it frees what needs it, prints an error message
|
||||||
/// in ::Gui_loading_error_message, and returns NULL.
|
/// in ::Gui_loading_error_message, and returns NULL.
|
||||||
byte * Load_font(const char * font_name);
|
byte * Load_font(const char * font_name, int is_main);
|
||||||
|
|
||||||
|
/// Load fonts for additional Unicode characters
|
||||||
|
void Load_Unicode_fonts(void);
|
||||||
|
|||||||
15
src/main.c
15
src/main.c
@ -745,12 +745,13 @@ int Init_program(int argc,char * argv[])
|
|||||||
Copy_preset_sieve(0);
|
Copy_preset_sieve(0);
|
||||||
|
|
||||||
// Font
|
// Font
|
||||||
if (!(Menu_font=Load_font(Config.Font_file)))
|
if (!(Menu_font=Load_font(Config.Font_file, 1)))
|
||||||
if (!(Menu_font=Load_font(DEFAULT_FONT_FILENAME)))
|
if (!(Menu_font=Load_font(DEFAULT_FONT_FILENAME, 1)))
|
||||||
{
|
{
|
||||||
printf("Unable to open the default font file: %s\n", DEFAULT_FONT_FILENAME);
|
printf("Unable to open the default font file: %s\n", DEFAULT_FONT_FILENAME);
|
||||||
Error(ERROR_GUI_MISSING);
|
Error(ERROR_GUI_MISSING);
|
||||||
}
|
}
|
||||||
|
Load_Unicode_fonts();
|
||||||
|
|
||||||
memcpy(Main.palette, Gfx->Default_palette, sizeof(T_Palette));
|
memcpy(Main.palette, Gfx->Default_palette, sizeof(T_Palette));
|
||||||
|
|
||||||
@ -993,6 +994,16 @@ void Program_shutdown(void)
|
|||||||
free(Gfx);
|
free(Gfx);
|
||||||
Gfx=NULL;
|
Gfx=NULL;
|
||||||
|
|
||||||
|
free(Menu_font);
|
||||||
|
Menu_font = NULL;
|
||||||
|
while (Unicode_fonts != NULL)
|
||||||
|
{
|
||||||
|
T_Unicode_Font * ufont = Unicode_fonts->Next;
|
||||||
|
free(Unicode_fonts->FontData);
|
||||||
|
free(Unicode_fonts);
|
||||||
|
Unicode_fonts = ufont;
|
||||||
|
}
|
||||||
|
|
||||||
// On prend bien soin de passer dans le répertoire initial:
|
// On prend bien soin de passer dans le répertoire initial:
|
||||||
if (chdir(Initial_directory)!=-1)
|
if (chdir(Initial_directory)!=-1)
|
||||||
{
|
{
|
||||||
|
|||||||
10
src/struct.h
10
src/struct.h
@ -549,7 +549,7 @@ typedef struct T_Selector_settings
|
|||||||
char Directory[MAX_PATH_CHARACTERS]; ///< Directory currently browsed
|
char Directory[MAX_PATH_CHARACTERS]; ///< Directory currently browsed
|
||||||
} T_Selector_settings;
|
} T_Selector_settings;
|
||||||
|
|
||||||
// structure for Main or Spare page global data
|
/// structure for Main or Spare page global data
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/// Palette
|
/// Palette
|
||||||
@ -618,4 +618,12 @@ typedef struct
|
|||||||
T_List_of_pages * backups;
|
T_List_of_pages * backups;
|
||||||
} T_Document;
|
} T_Document;
|
||||||
|
|
||||||
|
typedef struct T_Unicode_Font
|
||||||
|
{
|
||||||
|
struct T_Unicode_Font * Next;
|
||||||
|
dword FirstChar;
|
||||||
|
dword LastChar;
|
||||||
|
byte * FontData;
|
||||||
|
} T_Unicode_Font;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
81
src/unicode.c
Normal file
81
src/unicode.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* vim:expandtab:ts=2 sw=2:
|
||||||
|
*/
|
||||||
|
/* Grafx2 - The Ultimate 256-color bitmap paint program
|
||||||
|
|
||||||
|
Copyright 2018 Thomas Bernard
|
||||||
|
Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
|
||||||
|
|
||||||
|
Grafx2 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; version 2
|
||||||
|
of the License.
|
||||||
|
|
||||||
|
Grafx2 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 Grafx2; if not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "unicode.h"
|
||||||
|
|
||||||
|
size_t Unicode_strlen(const word * str)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
while(str[len] != 0)
|
||||||
|
len++;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// equivalent of strdup() for our Unicode strings
|
||||||
|
word * Unicode_strdup(const word * str)
|
||||||
|
{
|
||||||
|
size_t byte_size;
|
||||||
|
word * new_str;
|
||||||
|
|
||||||
|
byte_size = Unicode_strlen(str) * 2 + 2;
|
||||||
|
new_str = malloc(byte_size);
|
||||||
|
if (new_str != NULL)
|
||||||
|
memcpy(new_str, str, byte_size);
|
||||||
|
return new_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compare an unicode string with a regular Latin1 string
|
||||||
|
int Unicode_char_strcmp(const word * s1, const char * s2)
|
||||||
|
{
|
||||||
|
const byte * str2 = (const byte *)s2;
|
||||||
|
|
||||||
|
while (*s1 == *str2)
|
||||||
|
{
|
||||||
|
if (*s1 == 0) return 0;
|
||||||
|
s1++;
|
||||||
|
str2++;
|
||||||
|
}
|
||||||
|
return (*s1 > *str2) ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copy a regular Latin1 string to an unicode string
|
||||||
|
void Unicode_char_strlcpy(word * dst, const char * src, size_t len)
|
||||||
|
{
|
||||||
|
const byte * s = (const byte *)src;
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
return;
|
||||||
|
while (len > 1)
|
||||||
|
{
|
||||||
|
*dst = *s;
|
||||||
|
if (*s == '\0')
|
||||||
|
return;
|
||||||
|
dst++;
|
||||||
|
s++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
*dst = 0;
|
||||||
|
}
|
||||||
39
src/unicode.h
Normal file
39
src/unicode.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* vim:expandtab:ts=2 sw=2:
|
||||||
|
*/
|
||||||
|
/* Grafx2 - The Ultimate 256-color bitmap paint program
|
||||||
|
|
||||||
|
Copyright 2018 Thomas Bernard
|
||||||
|
Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
|
||||||
|
|
||||||
|
Grafx2 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; version 2
|
||||||
|
of the License.
|
||||||
|
|
||||||
|
Grafx2 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 Grafx2; if not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
#ifndef UNICODE_H_INCLUDED
|
||||||
|
#define UNICODE_H_INCLUDED
|
||||||
|
|
||||||
|
#include "struct.h"
|
||||||
|
|
||||||
|
/// equivalent of strlen() for out Unicode strings
|
||||||
|
/// return the number of characters (words), so there is twice as much bytes
|
||||||
|
size_t Unicode_strlen(const word * str);
|
||||||
|
|
||||||
|
/// equivalent of strdup() for our Unicode strings
|
||||||
|
word * Unicode_strdup(const word * str);
|
||||||
|
|
||||||
|
/// Compare an unicode string with a regular Latin1 string
|
||||||
|
int Unicode_char_strcmp(const word * s1, const char * s2);
|
||||||
|
|
||||||
|
/// Copy a regular Latin1 string to an unicode string
|
||||||
|
void Unicode_char_strlcpy(word * dst, const char * src, size_t len);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -708,13 +708,25 @@ void Print_general(short x,short y,const char * str,byte text_color,byte backgro
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draws a char in a window
|
/// Draws a char in a window
|
||||||
void Print_char_in_window(short x_pos,short y_pos,const unsigned char c,byte text_color,byte background_color)
|
void Print_char_in_window(short x_pos, short y_pos, unsigned int c,byte text_color,byte background_color)
|
||||||
{
|
{
|
||||||
short x,y;
|
short x,y;
|
||||||
byte *pixel;
|
const byte *pixel;
|
||||||
// Premier pixel du caractère
|
// Premier pixel du caractère
|
||||||
pixel=Menu_font + (c<<6);
|
if (c < 256)
|
||||||
|
pixel=Menu_font + (c<<6);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
T_Unicode_Font * ufont;
|
||||||
|
pixel=Menu_font + (1<<6); // dummy character
|
||||||
|
for (ufont = Unicode_fonts; ufont != NULL; ufont = ufont->Next)
|
||||||
|
if (ufont->FirstChar <= c && c <= ufont->LastChar)
|
||||||
|
{
|
||||||
|
pixel = ufont->FontData + ((c - ufont->FirstChar) << 6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (y=0;y<8;y++)
|
for (y=0;y<8;y++)
|
||||||
for (x=0;x<8;x++)
|
for (x=0;x<8;x++)
|
||||||
Pixel_in_window(x_pos+x, y_pos+y,
|
Pixel_in_window(x_pos+x, y_pos+y,
|
||||||
@ -739,16 +751,31 @@ void Print_in_window_limited(short x,short y,const char * str,byte size,byte tex
|
|||||||
void Print_in_window(short x,short y,const char * str,byte text_color,byte background_color)
|
void Print_in_window(short x,short y,const char * str,byte text_color,byte background_color)
|
||||||
{
|
{
|
||||||
short x_pos = x;
|
short x_pos = x;
|
||||||
int index;
|
const unsigned char * p = (const unsigned char *)str;
|
||||||
|
|
||||||
for (index=0;str[index]!='\0';index++)
|
while (*p !='\0')
|
||||||
{
|
{
|
||||||
Print_char_in_window(x,y,str[index],text_color,background_color);
|
Print_char_in_window(x,y,*p++,text_color,background_color);
|
||||||
x+=8;
|
x+=8;
|
||||||
}
|
}
|
||||||
Update_window_area(x_pos,y,8*strlen(str),8);
|
Update_window_area(x_pos,y,x-x_pos,8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Draws a string in a window
|
||||||
|
void Print_in_window_utf16(short x,short y,const word * str,byte text_color,byte background_color)
|
||||||
|
{
|
||||||
|
short x_pos = x;
|
||||||
|
const word * p = str;
|
||||||
|
|
||||||
|
while (*p != 0)
|
||||||
|
{
|
||||||
|
Print_char_in_window(x,y,*p++,text_color,background_color);
|
||||||
|
x+=8;
|
||||||
|
}
|
||||||
|
Update_window_area(x_pos,y,x-x_pos,8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Draws a string in the menu's status bar
|
// Draws a string in the menu's status bar
|
||||||
void Print_in_menu(const char * str, short position)
|
void Print_in_menu(const char * str, short position)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -67,8 +67,9 @@ word Palette_cells_Y(void);
|
|||||||
|
|
||||||
void Print_general(short x,short y,const char * str,byte text_color,byte background_color);
|
void Print_general(short x,short y,const char * str,byte text_color,byte background_color);
|
||||||
void Print_in_window(short x,short y,const char * str,byte text_color,byte background_color);
|
void Print_in_window(short x,short y,const char * str,byte text_color,byte background_color);
|
||||||
|
void Print_in_window_utf16(short x,short y,const word * str,byte text_color,byte background_color);
|
||||||
void Print_in_window_limited(short x,short y,const char * str,byte size,byte text_color,byte background_color);
|
void Print_in_window_limited(short x,short y,const char * str,byte size,byte text_color,byte background_color);
|
||||||
void Print_char_in_window(short x_pos,short y_pos,const unsigned char c,byte text_color,byte background_color);
|
void Print_char_in_window(short x_pos,short y_pos, unsigned int c,byte text_color,byte background_color);
|
||||||
void Print_in_menu(const char * str, short position);
|
void Print_in_menu(const char * str, short position);
|
||||||
void Print_coordinates(void);
|
void Print_coordinates(void);
|
||||||
void Print_filename(void);
|
void Print_filename(void);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user