SFont now uses T_GFX2_Surface instead of SDL_Surface

This commit is contained in:
Thomas Bernard 2018-06-23 21:40:05 +02:00
parent 6aaef13a6b
commit 3b69ccb1ec
5 changed files with 102 additions and 208 deletions

View File

@ -128,6 +128,7 @@
<ClCompile Include="..\..\src\recoil.c" /> <ClCompile Include="..\..\src\recoil.c" />
<ClCompile Include="..\..\src\saveini.c" /> <ClCompile Include="..\..\src\saveini.c" />
<ClCompile Include="..\..\src\setup.c" /> <ClCompile Include="..\..\src\setup.c" />
<ClCompile Include="..\..\src\SFont.c" />
<ClCompile Include="..\..\src\shade.c" /> <ClCompile Include="..\..\src\shade.c" />
<ClCompile Include="..\..\src\special.c" /> <ClCompile Include="..\..\src\special.c" />
<ClCompile Include="..\..\src\text.c" /> <ClCompile Include="..\..\src\text.c" />

View File

@ -180,6 +180,9 @@
<ClCompile Include="..\..\src\win32screen.c"> <ClCompile Include="..\..\src\win32screen.c">
<Filter>Fichiers sources</Filter> <Filter>Fichiers sources</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\SFont.c">
<Filter>Fichiers sources</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\src\brush.h"> <ClInclude Include="..\..\src\brush.h">

View File

@ -3,100 +3,64 @@
/* SFont: a simple font-library that uses special .pngs as fonts /* SFont: a simple font-library that uses special .pngs as fonts
Copyright (C) 2003 Karl Bartel Copyright (C) 2003 Karl Bartel
GrafX2 Modification
Copyright (c) 2018 Thomas Bernard
License: GPL or LGPL (at your choice) License: GPL or LGPL (at your choice)
WWW: http://www.linux-games.com/sfont/ WWW: http://www.linux-games.com/sfont/
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. along with this program; if not, see <http://www.gnu.org/licenses/>.
Karl Bartel Karl Bartel
Cecilienstr. 14 Cecilienstr. 14
12307 Berlin 12307 Berlin
GERMANY GERMANY
karlb@gmx.net karlb@gmx.net
*/ */
#if defined(USE_SDL) || defined(USE_SDL2)
#include <SDL.h>
#include <SDL_video.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "SFont.h" #include "SFont.h"
static Uint32 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y) SFont_Font* SFont_InitFont(T_GFX2_Surface * Surface)
{
Uint8 *bits;
Uint32 Bpp;
assert(X>=0);
assert(X<Surface->w);
Bpp = Surface->format->BytesPerPixel;
bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp;
// Get the pixel
switch(Bpp) {
case 1:
return *((Uint8 *)Surface->pixels + Y * Surface->pitch + X);
break;
case 2:
return *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X);
break;
case 3: { // Format/endian independent
Uint8 r, g, b;
r = *((bits)+Surface->format->Rshift/8);
g = *((bits)+Surface->format->Gshift/8);
b = *((bits)+Surface->format->Bshift/8);
return SDL_MapRGB(Surface->format, r, g, b);
}
break;
case 4:
return *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X);
break;
}
return -1;
}
SFont_Font* SFont_InitFont(SDL_Surface* Surface)
{ {
int x = 0, i = 33; int x = 0, i = 33;
Uint32 pixel; byte pixel;
SFont_Font* Font; SFont_Font* Font;
Uint32 pink; byte pink;
if (Surface == NULL) if (Surface == NULL)
return NULL; return NULL;
Font = (SFont_Font *) malloc(sizeof(SFont_Font)); Font = (SFont_Font *) malloc(sizeof(SFont_Font));
memset(Font, 0, sizeof(SFont_Font)); memset(Font, 0, sizeof(SFont_Font));
Font->Surface = Surface; Font->Surface = Surface;
SDL_LockSurface(Surface); pink = Get_GFX2_Surface_pixel(Surface, 0, 0);
pink = GetPixel(Surface, 0, 0);
while (x < Surface->w) { while (x < Surface->w) {
if (GetPixel(Surface, x, 0) != pink) { if (Get_GFX2_Surface_pixel(Surface, x, 0) != pink) {
Font->CharBegin[i]=x; Font->CharBegin[i]=x;
while((x < Surface->w) && (GetPixel(Surface, x, 0)!= pink)) while((x < Surface->w) && (Get_GFX2_Surface_pixel(Surface, x, 0)!= pink))
x++; x++;
Font->CharWidth[i]=x-Font->CharBegin[i]; Font->CharWidth[i]=x-Font->CharBegin[i];
i++; i++;
} }
x++; x++;
} }
// Create lowercase characters, if not present // Create lowercase characters, if not present
for (i=0; i <26; i++) for (i=0; i <26; i++)
{ {
@ -106,8 +70,8 @@ SFont_Font* SFont_InitFont(SDL_Surface* Surface)
Font->CharWidth['a'+i]=Font->CharWidth['A'+i]; Font->CharWidth['a'+i]=Font->CharWidth['A'+i];
} }
} }
// Determine space width. // Determine space width.
// This strange format doesn't allow font designer to write explicit // This strange format doesn't allow font designer to write explicit
// space as a character. // space as a character.
// Rule: A space should be as large as the character " if available, // Rule: A space should be as large as the character " if available,
@ -115,11 +79,8 @@ SFont_Font* SFont_InitFont(SDL_Surface* Surface)
Font->Space = Font->CharWidth[(int)'"']; Font->Space = Font->CharWidth[(int)'"'];
if (Font->Space<2) if (Font->Space<2)
Font->Space = Font->CharWidth[(int)'a']; Font->Space = Font->CharWidth[(int)'a'];
pixel = GetPixel(Surface, 0, Surface->h-1); pixel = Get_GFX2_Surface_pixel(Surface, 0, Surface->h-1);
SDL_UnlockSurface(Surface);
// No longer use SDL color keying
//SDL_SetColorKey(Surface, SDL_SRCCOLORKEY, pixel);
Font->Transparent=pixel; Font->Transparent=pixel;
return Font; return Font;
@ -127,28 +88,26 @@ SFont_Font* SFont_InitFont(SDL_Surface* Surface)
void SFont_FreeFont(SFont_Font* FontInfo) void SFont_FreeFont(SFont_Font* FontInfo)
{ {
SDL_FreeSurface(FontInfo->Surface); Free_GFX2_Surface(FontInfo->Surface);
free(FontInfo); free(FontInfo);
} }
void SFont_Write(SDL_Surface *Surface, const SFont_Font *Font, void SFont_Write(T_GFX2_Surface *Surface, const SFont_Font *Font,
int x, int y, const char *text) int x, int y, const char *text)
{ {
const char* c; const char* c;
SDL_Rect srcrect, dstrect; int line;
int height;
if(text == NULL) if(text == NULL)
return; return;
// these values won't change in the loop height = Font->Surface->h - 1;
srcrect.y = 1;
dstrect.y = y;
srcrect.h = dstrect.h = Font->Surface->h - 1;
for(c = text; *c != '\0' && x <= Surface->w ; c++) { for(c = text; *c != '\0' && x <= Surface->w ; c++) {
if (*c == '\n') { if (*c == '\n') {
dstrect.y += Font->Surface->h-1; y += height;
x=0; x = 0;
continue; continue;
} }
// skip spaces and nonprintable characters // skip spaces and nonprintable characters
@ -157,12 +116,11 @@ void SFont_Write(SDL_Surface *Surface, const SFont_Font *Font,
continue; continue;
} }
srcrect.w = Font->CharWidth[(int)*c]; for (line = 0; line < height && (y + line) < Surface->h; line++) {
dstrect.w = srcrect.w; memcpy(Surface->pixels + (y + line) * Surface->w + x,
srcrect.x = Font->CharBegin[(int)*c]; Font->Surface->pixels + (line + 1) * Font->Surface->w + Font->CharBegin[(int)*c],
dstrect.x = x; Font->CharWidth[(int)*c]);
}
SDL_BlitSurface(Font->Surface, &srcrect, Surface, &dstrect);
x += Font->CharWidth[(int)*c]; x += Font->CharWidth[(int)*c];
} }
@ -192,7 +150,7 @@ int SFont_TextWidth(const SFont_Font *Font, const char *text)
width += Font->Space; width += Font->Space;
continue; continue;
} }
width += Font->CharWidth[(int)*c]; width += Font->CharWidth[(int)*c];
} }
@ -209,7 +167,7 @@ int SFont_TextHeight(const SFont_Font* Font, const char *text)
nb_cr++; nb_cr++;
text++; text++;
} }
return (Font->Surface->h - 1) * (nb_cr+1); return (Font->Surface->h - 1) * (nb_cr+1);
} }
@ -223,4 +181,3 @@ void SFont_WriteCenter(SDL_Surface *Surface, const SFont_Font *Font,
y, text); y, text);
} }
*/ */
#endif

View File

@ -3,30 +3,33 @@
/* SFont: a simple font-library that uses special bitmaps as fonts /* SFont: a simple font-library that uses special bitmaps as fonts
Copyright (C) 2003 Karl Bartel Copyright (C) 2003 Karl Bartel
GrafX2 Modification
Copyright (c) 2018 Thomas Bernard
License: GPL or LGPL (at your choice) License: GPL or LGPL (at your choice)
WWW: http://www.linux-games.com/sfont/ WWW: http://www.linux-games.com/sfont/
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. along with this program; if not, see <http://www.gnu.org/licenses/>.
Karl Bartel Karl Bartel
Cecilienstr. 14 Cecilienstr. 14
12307 Berlin 12307 Berlin
GERMANY GERMANY
karlb@gmx.net karlb@gmx.net
*/ */
/************************************************************************ /************************************************************************
* SFONT - SDL Font Library by Karl Bartel <karlb@gmx.net> * * SFONT - SDL Font Library by Karl Bartel <karlb@gmx.net> *
* * * *
* All functions are explained below. For further information, take a * * All functions are explained below. For further information, take a *
@ -44,9 +47,9 @@
#ifndef _SFONT_H_ #ifndef _SFONT_H_
#define _SFONT_H_ #define _SFONT_H_
#include <SDL.h> #include "gfx2surface.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -55,7 +58,7 @@ extern "C" {
/// To load the fonts, load the font image into YourFont->Surface /// To load the fonts, load the font image into YourFont->Surface
/// and call InitFont( YourFont ); /// and call InitFont( YourFont );
typedef struct { typedef struct {
SDL_Surface *Surface; T_GFX2_Surface *Surface;
int CharBegin[256]; int CharBegin[256];
int CharWidth[256]; int CharWidth[256];
int Space; int Space;
@ -66,7 +69,7 @@ typedef struct {
/// Initializes the font. /// Initializes the font.
/// @param Font this contains the suface with the font. /// @param Font this contains the suface with the font.
/// The Surface must be loaded before calling this function /// The Surface must be loaded before calling this function
SFont_Font* SFont_InitFont (SDL_Surface *Font); SFont_Font* SFont_InitFont (T_GFX2_Surface *Font);
/// ///
/// Frees the font. /// Frees the font.
@ -81,7 +84,7 @@ void SFont_FreeFont(SFont_Font* Font);
/// @param text A string containing the text you want to blit. /// @param text A string containing the text you want to blit.
/// @param x Coordinates to start drawing. /// @param x Coordinates to start drawing.
/// @param y Coordinates to start drawing. /// @param y Coordinates to start drawing.
void SFont_Write(SDL_Surface *Surface, const SFont_Font *Font, int x, int y, void SFont_Write(T_GFX2_Surface *Surface, const SFont_Font *Font, int x, int y,
const char *text); const char *text);
/// Returns the width of "text" in pixels /// Returns the width of "text" in pixels
@ -90,8 +93,8 @@ int SFont_TextWidth(const SFont_Font* Font, const char *text);
int SFont_TextHeight(const SFont_Font* Font, const char *text); int SFont_TextHeight(const SFont_Font* Font, const char *text);
/// Blits a string to Surface with centered x position /// Blits a string to Surface with centered x position
void SFont_WriteCenter(SDL_Surface *Surface, const SFont_Font* Font, int y, //void SFont_WriteCenter(SDL_Surface *Surface, const SFont_Font* Font, int y,
const char *text); // const char *text);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -64,7 +64,6 @@
#if defined(USE_SDL) || defined(USE_SDL2) #if defined(USE_SDL) || defined(USE_SDL2)
#include <SDL_image.h> #include <SDL_image.h>
#include "SFont.h"
#include "sdlscreen.h" #include "sdlscreen.h"
#endif #endif
@ -75,6 +74,8 @@
#include "windows.h" #include "windows.h"
#include "misc.h" #include "misc.h"
#include "setup.h" #include "setup.h"
#include "loadsave.h"
#include "SFont.h"
typedef struct T_Font typedef struct T_Font
{ {
@ -693,109 +694,43 @@ byte *Render_text_Win32(const char *str, int font_number, int size, int antialia
} }
#endif #endif
#if defined(USE_SDL) || defined(USE_SDL2)
byte *Render_text_SFont(const char *str, int font_number, int *width, int *height, T_Palette palette) byte *Render_text_SFont(const char *str, int font_number, int *width, int *height, T_Palette palette)
{ {
SFont_Font *font; SFont_Font *font;
SDL_Surface * text_surface; T_GFX2_Surface * text_surface;
SDL_Surface *font_surface; T_GFX2_Surface *font_surface;
byte * new_brush; byte * new_brush = NULL;
SDL_Rect rectangle;
// Chargement de la fonte // Chargement de la fonte
font_surface=IMG_Load(Font_name(font_number)); font_surface = Load_surface(Font_name(font_number), NULL);
if (!font_surface) if (!font_surface)
{ {
char buffer[256]; Verbose_message("Warning", "Error loading font");
strcpy(buffer, "Error loading font.\n"); // TODO this leaves a non-erased cursor when the window closes.
strcat(buffer,IMG_GetError());
Verbose_message("Warning",buffer);
// TODO this leaves a non-erased cursor when the window closes.
return NULL; return NULL;
} }
// Font is 24bit: Perform a color reduction
if (font_surface->format->BitsPerPixel>8)
{
SDL_Surface * reduced_surface;
int x,y,color;
SDL_Color rgb;
reduced_surface=SDL_CreateRGBSurface(SDL_SWSURFACE, font_surface->w, font_surface->h, 8, 0, 0, 0, 0);
if (!reduced_surface)
{
SDL_FreeSurface(font_surface);
return NULL;
}
// Set the quick palette
for (color=0;color<256;color++)
{
rgb.r=((color & 0xE0)>>5)<<5;
rgb.g=((color & 0x1C)>>2)<<5;
rgb.b=((color & 0x03)>>0)<<6;
#if defined(USE_SDL)
SDL_SetColors(reduced_surface, &rgb, color, 1);
#else
//SDL_SetPaletteColors
#endif
}
// Perform reduction
for (y=0; y<font_surface->h; y++)
for (x=0; x<font_surface->w; x++)
{
SDL_GetRGB(Get_SDL_pixel_hicolor(font_surface, x, y), font_surface->format, &rgb.r, &rgb.g, &rgb.b);
color=((rgb.r >> 5) << 5) |
((rgb.g >> 5) << 2) |
((rgb.b >> 6));
Set_SDL_pixel_8(reduced_surface, x, y, color);
}
SDL_FreeSurface(font_surface);
font_surface=reduced_surface;
}
font=SFont_InitFont(font_surface); font=SFont_InitFont(font_surface);
if (!font) if (!font)
{ {
DEBUG("Font init failed",1); DEBUG("Font init failed",1);
SDL_FreeSurface(font_surface); Free_GFX2_Surface(font_surface);
return NULL;
}
// Calcul des dimensions
*height=SFont_TextHeight(font, str);
*width=SFont_TextWidth(font, str);
// Allocation d'une surface SDL
text_surface=SDL_CreateRGBSurface(SDL_SWSURFACE, *width, *height, 8, 0, 0, 0, 0);
// Copy palette
#if defined(USE_SDL)
SDL_SetPalette(text_surface, SDL_LOGPAL, font_surface->format->palette->colors, 0, 256);
#else
//SDL_SetPaletteColors(
#endif
// Fill with transparent color
rectangle.x=0;
rectangle.y=0;
rectangle.w=*width;
rectangle.h=*height;
SDL_FillRect(text_surface, &rectangle, font->Transparent);
// Rendu du texte
SFont_Write(text_surface, font, 0, 0, str);
if (!text_surface)
{
DEBUG("Rendering failed",2);
SFont_FreeFont(font);
return NULL;
}
new_brush=Surface_to_bytefield(text_surface, NULL);
if (!new_brush)
{
DEBUG("Converting failed",3);
SDL_FreeSurface(text_surface);
SFont_FreeFont(font);
return NULL; return NULL;
} }
Get_SDL_Palette(font_surface->format->palette, palette); // Calcul des dimensions
*height = SFont_TextHeight(font, str);
*width = SFont_TextWidth(font, str);
text_surface = New_GFX2_Surface(*width, *height);
// Fill with transparent color
memset(text_surface->pixels, font->Transparent, *width * *height);
// Rendu du texte
SFont_Write(text_surface, font, 0, 0, str);
// Copy palette
memcpy(palette, font_surface->palette, sizeof(T_Palette));
new_brush = text_surface->pixels; // "Steal" pixels from surface
// Swap current BG color with font's transparent color // Swap current BG color with font's transparent color
if (font->Transparent != Back_color) if (font->Transparent != Back_color)
@ -816,16 +751,15 @@ byte *Render_text_SFont(const char *str, int font_number, int *width, int *heigh
colmap[font->Transparent]=Back_color; colmap[font->Transparent]=Back_color;
colmap[Back_color]=font->Transparent; colmap[Back_color]=font->Transparent;
Remap_general_lowlevel(colmap, new_brush, new_brush, text_surface->w,text_surface->h, text_surface->w); Remap_general_lowlevel(colmap, new_brush, new_brush, text_surface->w, text_surface->h, text_surface->w);
} }
SDL_FreeSurface(text_surface);
SFont_FreeFont(font); SFont_FreeFont(font);
free(text_surface); // Do not call Free_GFX2_Surface() because pixels was stolen
return new_brush; return new_brush;
} }
#endif
// Crée une brosse à partir des paramètres de texte demandés. // Crée une brosse à partir des paramètres de texte demandés.
// Si cela réussit, la fonction place les dimensions dans width et height, // Si cela réussit, la fonction place les dimensions dans width et height,
@ -859,11 +793,7 @@ byte *Render_text(const char *str, int font_number, int size, int antialias, int
} }
else else
{ {
#if defined(USE_SDL) || defined(USE_SDL2)
return Render_text_SFont(str, font_number, width, height, palette); return Render_text_SFont(str, font_number, width, height, palette);
#else
return NULL;
#endif
} }
} }