mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-22 22:48:08 +03:00
@@ -67,6 +67,7 @@ else()
|
||||
endif()
|
||||
|
||||
optional_pkg_check_modules(SDL2MIXER IMPORTED_TARGET SDL2_mixer)
|
||||
optional_pkg_check_modules(SDL2TTF IMPORTED_TARGET SDL2_ttf)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -204,6 +205,11 @@ if (FREETYPE_FOUND)
|
||||
list(APPEND SUMMARY_FONT "freetype2")
|
||||
set(ENABLE_FT2 1)
|
||||
endif()
|
||||
if (NOT X11_FOUND AND SDL2TTF_FOUND)
|
||||
list(APPEND SRC_FONT font_sdlttf.c)
|
||||
list(APPEND SUMMARY_FONT "SDL_ttf")
|
||||
set(ENABLE_SDLTTF 1)
|
||||
endif()
|
||||
if (NOT SRC_FONT)
|
||||
message(FATAL_ERROR "*** No font device available ***")
|
||||
endif()
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#cmakedefine ENABLE_NLS @ENABLE_NLS@
|
||||
#cmakedefine ENABLE_SDL @ENABLE_SDL@
|
||||
#cmakedefine ENABLE_SDLMIXER @ENABLE_SDLMIXER@
|
||||
#cmakedefine ENABLE_SDLTTF @ENABLE_SDLTTF@
|
||||
#cmakedefine ENABLE_X11FONT @ENABLE_X11FONT@
|
||||
|
||||
#cmakedefine CDROM_DEVICE "@CDROM_DEVICE@"
|
||||
|
||||
@@ -97,6 +97,9 @@ else() # non-emscripten
|
||||
if (SDL2MIXER_FOUND)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::SDL2MIXER)
|
||||
endif()
|
||||
if (SDL2TTF_FOUND)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::SDL2TTF)
|
||||
endif()
|
||||
|
||||
install(TARGETS xsystem35 RUNTIME DESTINATION bin)
|
||||
endif()
|
||||
|
||||
@@ -43,6 +43,11 @@ void font_init(int dev) {
|
||||
case FONT_FT2:
|
||||
nact->ags.font = font_ft2_new();
|
||||
break;
|
||||
#endif
|
||||
#ifdef ENABLE_SDLTTF
|
||||
case FONT_SDLTTF:
|
||||
nact->ags.font = font_sdlttf_new();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
#ifndef ENABLE_SDL
|
||||
|
||||
+80
-26
@@ -1,11 +1,15 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL_ttf.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
#include "font.h"
|
||||
#include "sdl_private.h"
|
||||
#include "utfsjis.h"
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
@@ -17,14 +21,14 @@ typedef struct {
|
||||
static FontTable fonttbl[FONTTABLEMAX];
|
||||
static int fontcnt = 0;
|
||||
|
||||
static TTF_Font *fontset;
|
||||
static FontTable *fontset;
|
||||
|
||||
static FONT *this;
|
||||
|
||||
static void font_insert(int size, int type, ttfont *fontset) {
|
||||
static void font_insert(int size, int type, TTF_Font *font) {
|
||||
fonttbl[fontcnt].size = size;
|
||||
fonttbl[fontcnt].type = type;
|
||||
fonttbl[fontcnt].id = fontset;
|
||||
fonttbl[fontcnt].id = font;
|
||||
|
||||
if (fontcnt >= (FONTTABLEMAX -1)) {
|
||||
WARNING("Font table is full.\n");
|
||||
@@ -44,14 +48,14 @@ static FontTable *font_lookup(int size, int type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void font_ttf_sel_font(int type, int size) {
|
||||
static void font_sdlttf_sel_font(int type, int size) {
|
||||
FontTable *tbl;
|
||||
|
||||
|
||||
if (NULL == (tbl = font_lookup(size, type))) {
|
||||
TTF_Font *fs;
|
||||
|
||||
fs = TTF_OpenFont(this->name[type], size);
|
||||
fs = TTF_OpenFontIndex(this->name[type], size, this->face[type]);
|
||||
|
||||
if (fs == NULL) {
|
||||
WARNING("%s is not found:\n", this->name[type]);
|
||||
@@ -59,38 +63,89 @@ static void font_ttf_sel_font(int type, int size) {
|
||||
}
|
||||
|
||||
font_insert(size, type, fs);
|
||||
fontset = fs;
|
||||
fontset = &fonttbl[fontcnt - 1];
|
||||
} else {
|
||||
fontset = tbl->id;
|
||||
fontset = tbl;
|
||||
}
|
||||
}
|
||||
|
||||
static void *font_sdlttf_get_glyph(unsigned char *msg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// SDL can't blit ARGB to an indexed bitmap properly, so we do it ourselves.
|
||||
static void sdl_drawAntiAlias_8bpp(int dstx, int dsty, SDL_Surface *src, unsigned long col)
|
||||
{
|
||||
SDL_LockSurface(sdl_dib);
|
||||
|
||||
Uint8 cache[256*7];
|
||||
memset(cache, 0, 256);
|
||||
|
||||
for (int y = 0; y < src->h && dsty + y < sdl_dib->h; y++) {
|
||||
BYTE *sp = (BYTE*)src->pixels + y * src->pitch;
|
||||
BYTE *dp = (BYTE*)sdl_dib->pixels + (dsty + y) * sdl_dib->pitch + dstx;
|
||||
for (int x = 0; x < src->w && dstx + x < sdl_dib->w; x++) {
|
||||
Uint8 r, g, b, alpha;
|
||||
SDL_GetRGBA(*((Uint32*)sp), src->format, &r, &g, &b, &alpha);
|
||||
alpha = alpha >> 5; // reduce bit depth
|
||||
if (!alpha) {
|
||||
// Transparent, do nothing
|
||||
} else if (alpha == 7) {
|
||||
*dp = col; // Fully opaque
|
||||
} else if (cache[*dp] & 1 << alpha) {
|
||||
*dp = cache[alpha << 8 | *dp]; // use cached value
|
||||
} else {
|
||||
// find nearest color in palette
|
||||
cache[*dp] |= 1 << alpha;
|
||||
int c = sdl_nearest_color(
|
||||
(sdl_col[col].r * alpha + sdl_col[*dp].r * (7 - alpha)) / 7,
|
||||
(sdl_col[col].g * alpha + sdl_col[*dp].g * (7 - alpha)) / 7,
|
||||
(sdl_col[col].b * alpha + sdl_col[*dp].b * (7 - alpha)) / 7);
|
||||
cache[alpha << 8 | *dp] = c;
|
||||
*dp = c;
|
||||
}
|
||||
sp += src->format->BytesPerPixel;
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(sdl_dib);
|
||||
}
|
||||
|
||||
static int font_sdlttf_draw_glyph(int x, int y, unsigned char *str, int cl) {
|
||||
SDL_Surface *fs;
|
||||
SDL_Color fg;
|
||||
SDL_Rect r_src, r_dst;
|
||||
int w, h;
|
||||
int w, h, maxy;
|
||||
BYTE *conv;
|
||||
|
||||
fg = SDL_MapRGB(sdl_dib->format,
|
||||
sdl_col[cl].r, sdl_col[cl].g, sdl_col[cl].b);
|
||||
if (!*str)
|
||||
return 0;
|
||||
|
||||
conv = sjis2lang(str);
|
||||
if (this->antialiase_on) {
|
||||
fs = TTF_RenderText_Shaded(fontset, str, cl);
|
||||
fs = TTF_RenderUTF8_Blended(fontset->id, conv, sdl_col[cl]);
|
||||
} else {
|
||||
fs = TTF_RenderText_Solid(fonset, str, cl);
|
||||
fs = TTF_RenderText_Solid(fontset->id, conv, sdl_col[cl]);
|
||||
}
|
||||
if (!fs) {
|
||||
WARNING("Text rendering failed: %s\n", TTF_GetError());
|
||||
free(conv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TTF_SizeText(fontset, str, &w, &h);
|
||||
TTF_SizeUTF8(fontset->id, conv, &w, &h);
|
||||
y = max(0, y - (TTF_FontAscent(fontset->id) - fontset->size * 0.9));
|
||||
|
||||
setRect(r_src, 0, 0, w, h);
|
||||
setRect(r_dst, x, y, w, h);
|
||||
|
||||
SDL_LockSurface(sdl_dib);
|
||||
SDL_BlitSurface(fs, &r_src, sdl_dib, &r_dst);
|
||||
SDL_UnlockSurface(sdl_dib);
|
||||
if (sdl_dib->format->BitsPerPixel == 8 && this->antialiase_on) {
|
||||
sdl_drawAntiAlias_8bpp(x, y, fs, cl);
|
||||
} else {
|
||||
setRect(r_src, 0, 0, w, h);
|
||||
setRect(r_dst, x, y, w, h);
|
||||
SDL_BlitSurface(fs, &r_src, sdl_dib, &r_dst);
|
||||
}
|
||||
|
||||
SDL_FreeSurface(fs);
|
||||
free(conv);
|
||||
|
||||
return w;
|
||||
}
|
||||
@@ -99,7 +154,7 @@ static boolean drawable() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
FONT *font_ttf_new() {
|
||||
FONT *font_sdlttf_new() {
|
||||
FONT *f = malloc(sizeof(FONT));
|
||||
|
||||
f->sel_font = font_sdlttf_sel_font;
|
||||
@@ -108,13 +163,12 @@ FONT *font_ttf_new() {
|
||||
f->self_drawable = drawable;
|
||||
f->antialiase_on = FALSE;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
fontmaps[i].etype = -1;
|
||||
}
|
||||
|
||||
TTF_Init();
|
||||
if (TTF_Init() == -1)
|
||||
SYSERROR("Failed to intialize SDL_ttf: %s\n", TTF_GetError());
|
||||
|
||||
this = f;
|
||||
|
||||
NOTICE("FontDevice SDL_ttf\n");
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
+2
-2
@@ -362,7 +362,7 @@ static SDL_Surface *com2alphasurface(agsurface_t *src, int cl) {
|
||||
return s;
|
||||
}
|
||||
|
||||
static int nearest_color(int r, int g, int b) {
|
||||
int sdl_nearest_color(int r, int g, int b) {
|
||||
int i, col, mind = INT_MAX;
|
||||
for (i = 0; i < 256; i++) {
|
||||
int dr = r - sdl_col[i].r;
|
||||
@@ -397,7 +397,7 @@ static void sdl_drawAntiAlias_8bpp(int dstx, int dsty, agsurface_t *src, unsigne
|
||||
*dp = cache[alpha << 8 | *dp];
|
||||
} else {
|
||||
cache[*dp] |= 1 << alpha;
|
||||
int c = nearest_color(
|
||||
int c = sdl_nearest_color(
|
||||
(sdl_col[col].r * alpha + sdl_col[*dp].r * (7 - alpha)) / 7,
|
||||
(sdl_col[col].g * alpha + sdl_col[*dp].g * (7 - alpha)) / 7,
|
||||
(sdl_col[col].b * alpha + sdl_col[*dp].b * (7 - alpha)) / 7);
|
||||
|
||||
@@ -62,6 +62,7 @@ struct sdl_private_data {
|
||||
|
||||
extern void sdl_cursor_init(void);
|
||||
extern void sdl_shadow_init(void);
|
||||
extern int sdl_nearest_color(int r, int g, int b);
|
||||
|
||||
#define SDL_AllocSurface(flags,w,h,d,r,g,b,a) SDL_CreateRGBSurface(0,w,h,d,r,g,b,a)
|
||||
|
||||
|
||||
+13
-13
@@ -99,12 +99,16 @@ static char *fontname_tt[FONTTYPEMAX];
|
||||
static boolean isjix0213_tt[FONTTYPEMAX];
|
||||
static char fontface[FONTTYPEMAX];
|
||||
|
||||
#ifdef ENABLE_SDL
|
||||
static fontdev_t fontdev = FONT_FT2;
|
||||
#ifdef ENABLE_SDLTTF
|
||||
#define DEFAULT_FONT_DEVICE FONT_SDLTTF
|
||||
#elif defined(ENABLE_SDL)
|
||||
#define DEFAULT_FONT_DEVICE FONT_FT2
|
||||
#else
|
||||
static fontdev_t fontdev = FONT_X11;
|
||||
#define DEFAULT_FONT_DEVICE FONT_X11
|
||||
#endif
|
||||
|
||||
static fontdev_t fontdev = DEFAULT_FONT_DEVICE;
|
||||
|
||||
/* antialias on from command line */
|
||||
static boolean font_antialias;
|
||||
static boolean font_noantialias;
|
||||
@@ -235,26 +239,22 @@ void sys_exit(int code) {
|
||||
}
|
||||
|
||||
static int check_fontdev(char *devname) {
|
||||
#ifdef ENABLE_SDLTTF
|
||||
if (0 == strcmp(devname, "sdl")) {
|
||||
return FONT_SDLTTF;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_FT2
|
||||
if (0 == strcmp(devname, "ft2")) {
|
||||
return FONT_FT2;
|
||||
}
|
||||
if (0 == strcmp(devname, "ttf")) {
|
||||
return FONT_FT2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_X11FONT
|
||||
if (0 == strcmp(devname, "x11")) {
|
||||
return FONT_X11;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SDL
|
||||
return FONT_FT2;
|
||||
#else
|
||||
return FONT_X11;
|
||||
#endif
|
||||
return DEFAULT_FONT_DEVICE;
|
||||
}
|
||||
|
||||
static void storeDataName(int type, int no, char *src) {
|
||||
|
||||
Reference in New Issue
Block a user