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;
|
||||
selected_font = Window_attribute2; // Get the index of the chosen 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)
|
||||
{
|
||||
free(Menu_font);
|
||||
@ -1498,7 +1498,7 @@ void Button_Skins(void)
|
||||
Set_current_skin(skinsdir, gfx);
|
||||
}
|
||||
// (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)
|
||||
{
|
||||
const char * fname;
|
||||
|
||||
@ -646,6 +646,9 @@ GFX2_GLOBAL byte Resolution_in_command_line;
|
||||
/// Pointer to the font selected for menus.
|
||||
GFX2_GLOBAL byte * Menu_font;
|
||||
|
||||
/// additional fonts for unicode characters
|
||||
GFX2_GLOBAL T_Unicode_Font * Unicode_fonts;
|
||||
|
||||
/// Pointer to the current active skin.
|
||||
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 -----
|
||||
|
||||
byte Parse_font(SDL_Surface * image, byte * font)
|
||||
static byte * Parse_font(SDL_Surface * image, int is_main)
|
||||
{
|
||||
byte * font;
|
||||
int character;
|
||||
byte color;
|
||||
int x, y;
|
||||
int chars_per_line;
|
||||
int character_count;
|
||||
|
||||
// Check image size
|
||||
if (image->w % 8)
|
||||
{
|
||||
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");
|
||||
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;
|
||||
|
||||
for (character=0; character < 256; character++)
|
||||
for (character=0; character < character_count; character++)
|
||||
{
|
||||
for (y=0; y<8; y++)
|
||||
{
|
||||
@ -732,19 +741,20 @@ byte Parse_font(SDL_Surface * image, byte * font)
|
||||
if (color > 1)
|
||||
{
|
||||
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.
|
||||
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];
|
||||
SDL_Surface * image;
|
||||
|
||||
@ -754,13 +764,6 @@ byte * Load_font(const char * font_name)
|
||||
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
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
font = Parse_font(image, is_main);
|
||||
SDL_FreeSurface(image);
|
||||
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:
|
||||
|
||||
|
||||
@ -47,4 +47,7 @@ extern char Gui_loading_error_message[512];
|
||||
/// successful.
|
||||
/// If an error is encountered, it frees what needs it, prints an error message
|
||||
/// 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);
|
||||
|
||||
// Font
|
||||
if (!(Menu_font=Load_font(Config.Font_file)))
|
||||
if (!(Menu_font=Load_font(DEFAULT_FONT_FILENAME)))
|
||||
if (!(Menu_font=Load_font(Config.Font_file, 1)))
|
||||
if (!(Menu_font=Load_font(DEFAULT_FONT_FILENAME, 1)))
|
||||
{
|
||||
printf("Unable to open the default font file: %s\n", DEFAULT_FONT_FILENAME);
|
||||
Error(ERROR_GUI_MISSING);
|
||||
}
|
||||
Load_Unicode_fonts();
|
||||
|
||||
memcpy(Main.palette, Gfx->Default_palette, sizeof(T_Palette));
|
||||
|
||||
@ -993,6 +994,16 @@ void Program_shutdown(void)
|
||||
free(Gfx);
|
||||
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:
|
||||
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
|
||||
} T_Selector_settings;
|
||||
|
||||
// structure for Main or Spare page global data
|
||||
/// structure for Main or Spare page global data
|
||||
typedef struct
|
||||
{
|
||||
/// Palette
|
||||
@ -618,4 +618,12 @@ typedef struct
|
||||
T_List_of_pages * backups;
|
||||
} T_Document;
|
||||
|
||||
typedef struct T_Unicode_Font
|
||||
{
|
||||
struct T_Unicode_Font * Next;
|
||||
dword FirstChar;
|
||||
dword LastChar;
|
||||
byte * FontData;
|
||||
} T_Unicode_Font;
|
||||
|
||||
#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
|
||||
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;
|
||||
byte *pixel;
|
||||
const byte *pixel;
|
||||
// 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 (x=0;x<8;x++)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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
|
||||
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_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_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_coordinates(void);
|
||||
void Print_filename(void);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user