190 | 190 |
#define DIVIDE_BY_255(x) DIVIDE_BY_255_SIGNED(x, 1)
|
191 | 191 |
|
192 | 192 |
|
193 | |
#define CACHED_METRICS 0x10
|
|
193 |
#define CACHED_METRICS 0x20
|
|
194 |
|
194 | 195 |
#define CACHED_BITMAP 0x01
|
195 | 196 |
#define CACHED_PIXMAP 0x02
|
196 | 197 |
#define CACHED_COLOR 0x04
|
197 | |
#define CACHED_SUBPIX 0x08
|
|
198 |
#define CACHED_LCD 0x08
|
|
199 |
#define CACHED_SUBPIX 0x10
|
198 | 200 |
|
199 | 201 |
|
200 | 202 |
typedef struct {
|
|
322 | 324 |
typedef enum {
|
323 | 325 |
RENDER_SOLID = 0,
|
324 | 326 |
RENDER_SHADED,
|
325 | |
RENDER_BLENDED
|
|
327 |
RENDER_BLENDED,
|
|
328 |
RENDER_LCD
|
326 | 329 |
} render_mode_t;
|
327 | 330 |
|
328 | 331 |
typedef enum {
|
|
347 | 350 |
SDL_Color fg, SDL_Color bg, Uint32 wrapLength, render_mode_t render_mode);
|
348 | 351 |
|
349 | 352 |
static SDL_INLINE int Find_GlyphByIndex(TTF_Font *font, FT_UInt idx,
|
350 | |
int want_bitmap, int want_pixmap, int want_color, int want_subpixel,
|
|
353 |
int want_bitmap, int want_pixmap, int want_color, int want_lcd, int want_subpixel,
|
351 | 354 |
int translation, c_glyph **out_glyph, TTF_Image **out_image);
|
352 | 355 |
|
353 | 356 |
static void Flush_Cache(TTF_Font *font);
|
|
419 | 422 |
dst = (Uint32 *)((Uint8 *)dst + dstskip);
|
420 | 423 |
}
|
421 | 424 |
}
|
|
425 |
}
|
|
426 |
|
|
427 |
/* Blend with LCD rendering */
|
|
428 |
static SDL_INLINE void BG_Blended_LCD(const TTF_Image *image, Uint32 *destination, Sint32 srcskip, Uint32 dstskip, SDL_Color *fg)
|
|
429 |
{
|
|
430 |
const Uint32 *src = (Uint32 *)image->buffer;
|
|
431 |
Uint32 *dst = destination;
|
|
432 |
Uint32 width = image->width;
|
|
433 |
Uint32 height = image->rows;
|
|
434 |
|
|
435 |
Uint32 tmp, bg;
|
|
436 |
Uint32 r, g, b;
|
|
437 |
Uint8 fg_r, fg_g, fg_b;
|
|
438 |
Uint8 bg_r, bg_g, bg_b;
|
|
439 |
Uint32 bg_a;
|
|
440 |
|
|
441 |
int x, y = 0;
|
|
442 |
|
|
443 |
fg_r = fg->r;
|
|
444 |
fg_g = fg->g;
|
|
445 |
fg_b = fg->b;
|
|
446 |
|
|
447 |
while (height--) {
|
|
448 |
y++;
|
|
449 |
x = 0;
|
|
450 |
/* *INDENT-OFF* */
|
|
451 |
DUFFS_LOOP4(
|
|
452 |
x++;
|
|
453 |
tmp = *src++;
|
|
454 |
|
|
455 |
if (tmp) {
|
|
456 |
bg = *dst;
|
|
457 |
|
|
458 |
bg_a = bg & 0xff000000;
|
|
459 |
bg_r = (bg >> 16) & 0xff;
|
|
460 |
bg_g = (bg >> 8) & 0xff;
|
|
461 |
bg_b = (bg >> 0) & 0xff;
|
|
462 |
|
|
463 |
r = (tmp >> 16) & 0xff;
|
|
464 |
g = (tmp >> 8) & 0xff;
|
|
465 |
b = (tmp >> 0) & 0xff;
|
|
466 |
|
|
467 |
r = fg_r * r + bg_r * (255 - r) + 127;
|
|
468 |
r = DIVIDE_BY_255(r);
|
|
469 |
|
|
470 |
g = fg_g * g + bg_g * (255 - g) + 127;
|
|
471 |
g = DIVIDE_BY_255(g);
|
|
472 |
|
|
473 |
b = fg_b * b + bg_b * (255 - b) + 127;
|
|
474 |
b = DIVIDE_BY_255(b);
|
|
475 |
|
|
476 |
r <<= 16;
|
|
477 |
g <<= 8;
|
|
478 |
b <<= 0;
|
|
479 |
|
|
480 |
*dst = r | g | b | bg_a;
|
|
481 |
}
|
|
482 |
dst++;
|
|
483 |
|
|
484 |
, width);
|
|
485 |
/* *INDENT-ON* */
|
|
486 |
src = (const Uint32 *)((const Uint8 *)src + srcskip);
|
|
487 |
dst = (Uint32 *)((Uint8 *)dst + dstskip);
|
|
488 |
}
|
|
489 |
|
422 | 490 |
}
|
423 | 491 |
|
424 | 492 |
#if TTF_USE_SDF
|
|
949 | 1017 |
/* Wrapped mode with an unbroken line: 'line_width' is greater that 'textbuf->w' */
|
950 | 1018 |
line_width = SDL_min(line_width, textbuf->w);
|
951 | 1019 |
|
952 | |
if (render_mode == RENDER_BLENDED) {
|
|
1020 |
if (render_mode == RENDER_BLENDED || render_mode == RENDER_LCD) {
|
953 | 1021 |
while (line_thickness--) {
|
954 | 1022 |
SDL_memset4(dst, color, line_width);
|
955 | 1023 |
dst += textbuf->pitch;
|
|
962 | 1030 |
}
|
963 | 1031 |
}
|
964 | 1032 |
|
965 | |
static void clip_glyph(int *_x, int *_y, TTF_Image *image, const SDL_Surface *textbuf)
|
|
1033 |
static void clip_glyph(int *_x, int *_y, TTF_Image *image, const SDL_Surface *textbuf, int is_lcd)
|
966 | 1034 |
{
|
967 | 1035 |
int above_w;
|
968 | 1036 |
int above_h;
|
|
970 | 1038 |
int y = *_y;
|
971 | 1039 |
|
972 | 1040 |
int srcbpp = 1;
|
973 | |
if (image->is_color) {
|
974 | |
/* This isn't tested because colored image never ends up left clipped */
|
|
1041 |
if (image->is_color || is_lcd) {
|
975 | 1042 |
srcbpp = 4;
|
976 | 1043 |
}
|
977 | 1044 |
|
|
1041 | 1108 |
#pragma GCC diagnostic push
|
1042 | 1109 |
#pragma GCC diagnostic ignored "-Wunused-value"
|
1043 | 1110 |
#endif
|
1044 | |
#define BUILD_RENDER_LINE(NAME, IS_BLENDED, IS_BLENDED_OPAQUE, WB_WP_WC, WS, BLIT_GLYPH_BLENDED_OPAQUE_OPTIM, BLIT_GLYPH_BLENDED_OPTIM, BLIT_GLYPH_OPTIM) \
|
|
1111 |
#define BUILD_RENDER_LINE(NAME, IS_BLENDED, IS_BLENDED_OPAQUE, IS_LCD, WB_WP_WC, WS, BLIT_GLYPH_BLENDED_OPAQUE_OPTIM, BLIT_GLYPH_BLENDED_OPTIM, BLIT_GLYPH_OPTIM) \
|
1045 | 1112 |
\
|
1046 | 1113 |
static SDL_INLINE \
|
1047 | |
int Render_Line_##NAME(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, Uint8 fg_alpha) \
|
|
1114 |
int Render_Line_##NAME(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, SDL_Color *fg) \
|
1048 | 1115 |
{ \
|
1049 | 1116 |
const int alignment = Get_Alignement() - 1; \
|
1050 | |
const int bpp = ((IS_BLENDED) ? 4 : 1); \
|
|
1117 |
const int bpp = ((IS_BLENDED || IS_LCD) ? 4 : 1); \
|
1051 | 1118 |
unsigned int i; \
|
|
1119 |
Uint8 fg_alpha = (fg ? fg->a : 0); \
|
1052 | 1120 |
for (i = 0; i < font->pos_len; i++) { \
|
1053 | 1121 |
FT_UInt idx = font->pos_buf[i].index; \
|
1054 | 1122 |
int x = font->pos_buf[i].x; \
|
|
1085 | 1153 |
srcskip = image->pitch - image->width; \
|
1086 | 1154 |
dstskip = textbuf->pitch - image->width * bpp; \
|
1087 | 1155 |
/* Render glyph at (x, y) with optimized copy functions */ \
|
1088 | |
if (!IS_BLENDED || image->is_color == 0) { \
|
|
1156 |
if (IS_LCD) { \
|
|
1157 |
image->buffer = saved_buffer; \
|
|
1158 |
image->buffer += alignment; \
|
|
1159 |
image->width = saved_width; \
|
|
1160 |
dst = (Uint8 *)textbuf->pixels + y * textbuf->pitch + x * bpp; \
|
|
1161 |
/* Compute srcskip, dstskip */ \
|
|
1162 |
srcskip = image->pitch - 4 * image->width; \
|
|
1163 |
dstskip = textbuf->pitch - image->width * bpp; \
|
|
1164 |
BG_Blended_LCD(image, (Uint32 *)dst, srcskip, dstskip, fg); \
|
|
1165 |
} else if (!IS_BLENDED || image->is_color == 0) { \
|
1089 | 1166 |
if (IS_BLENDED_OPAQUE) { \
|
1090 | 1167 |
BLIT_GLYPH_BLENDED_OPAQUE_OPTIM(image, (Uint32 *)dst, srcskip, dstskip); \
|
1091 | 1168 |
} else if (IS_BLENDED) { \
|
|
1109 | 1186 |
/* Modify a copy, and clip it */ \
|
1110 | 1187 |
TTF_Image image_clipped = *image; \
|
1111 | 1188 |
/* Intersect image glyph at (x,y) with textbuf */ \
|
1112 | |
clip_glyph(&x, &y, &image_clipped, textbuf); \
|
|
1189 |
clip_glyph(&x, &y, &image_clipped, textbuf, IS_LCD); \
|
1113 | 1190 |
/* Compute dst */ \
|
1114 | 1191 |
dst = (Uint8 *)textbuf->pixels + y * textbuf->pitch + x * bpp; \
|
1115 | 1192 |
/* Compute srcskip, dstskip */ \
|
1116 | 1193 |
srcskip = image_clipped.pitch - image_clipped.width; \
|
1117 | 1194 |
dstskip = textbuf->pitch - image_clipped.width * bpp; \
|
1118 | 1195 |
/* Render glyph at (x, y) */ \
|
1119 | |
if (!IS_BLENDED || image->is_color == 0) { \
|
|
1196 |
if (IS_LCD) { \
|
|
1197 |
srcskip -= 3 * image_clipped.width; \
|
|
1198 |
BG_Blended_LCD(&image_clipped, (Uint32 *)dst, srcskip, dstskip, fg); \
|
|
1199 |
} else if (!IS_BLENDED || image->is_color == 0) { \
|
1120 | 1200 |
if (IS_BLENDED_OPAQUE) { \
|
1121 | 1201 |
BG_Blended_Opaque(&image_clipped, (Uint32 *)dst, srcskip, dstskip); \
|
1122 | 1202 |
} else if (IS_BLENDED) { \
|
|
1139 | 1219 |
} \
|
1140 | 1220 |
\
|
1141 | 1221 |
|
1142 | |
#define BITMAP CACHED_BITMAP, 0, 0
|
1143 | |
#define PIXMAP 0, CACHED_PIXMAP, 0
|
1144 | |
#define COLOR 0, 0, CACHED_COLOR
|
|
1222 |
#define BITMAP CACHED_BITMAP, 0, 0, 0
|
|
1223 |
#define PIXMAP 0, CACHED_PIXMAP, 0, 0
|
|
1224 |
#define COLOR 0, 0, CACHED_COLOR, 0
|
|
1225 |
#define LCD 0, 0, 0, CACHED_LCD
|
1145 | 1226 |
|
1146 | 1227 |
#define SUBPIX CACHED_SUBPIX
|
1147 | 1228 |
|
1148 | |
/* BUILD_RENDER_LINE(NAME, IS_BLENDED, IS_BLENDED_OPAQUE, WANT_BITMAP_PIXMAP_COLOR, WANT_SUBPIXEL, BLIT_GLYPH_BLENDED_OPAQUE_OPTIM, BLIT_GLYPH_BLENDED_OPTIM, BLIT_GLYPH_OPTIM) */
|
|
1229 |
/* BUILD_RENDER_LINE(NAME, IS_BLENDED, IS_BLENDED_OPAQUE, WANT_BITMAP_PIXMAP_COLOR_LCD, WANT_SUBPIXEL, BLIT_GLYPH_BLENDED_OPAQUE_OPTIM, BLIT_GLYPH_BLENDED_OPTIM, BLIT_GLYPH_OPTIM) */
|
1149 | 1230 |
|
1150 | 1231 |
#if defined(HAVE_SSE2_INTRINSICS)
|
1151 | |
BUILD_RENDER_LINE(SSE_Shaded , 0, 0, PIXMAP, 0 , , , BG_SSE )
|
1152 | |
BUILD_RENDER_LINE(SSE_Blended , 1, 0, COLOR, 0 , , BG_Blended_SSE , )
|
1153 | |
BUILD_RENDER_LINE(SSE_Blended_Opaque , 1, 1, COLOR, 0 , BG_Blended_Opaque_SSE , , )
|
1154 | |
BUILD_RENDER_LINE(SSE_Solid , 0, 0, BITMAP, 0 , , , BG_SSE )
|
1155 | |
BUILD_RENDER_LINE(SSE_Shaded_SP , 0, 0, PIXMAP, SUBPIX, , , BG_SSE )
|
1156 | |
BUILD_RENDER_LINE(SSE_Blended_SP , 1, 0, COLOR, SUBPIX, , BG_Blended_SSE , )
|
1157 | |
BUILD_RENDER_LINE(SSE_Blended_Opaque_SP , 1, 1, COLOR, SUBPIX, BG_Blended_Opaque_SSE , , )
|
|
1232 |
BUILD_RENDER_LINE(SSE_Shaded , 0, 0, 0, PIXMAP, 0 , , , BG_SSE )
|
|
1233 |
BUILD_RENDER_LINE(SSE_Blended , 1, 0, 0, COLOR, 0 , , BG_Blended_SSE , )
|
|
1234 |
BUILD_RENDER_LINE(SSE_Blended_Opaque , 1, 1, 0, COLOR, 0 , BG_Blended_Opaque_SSE , , )
|
|
1235 |
BUILD_RENDER_LINE(SSE_Solid , 0, 0, 0, BITMAP, 0 , , , BG_SSE )
|
|
1236 |
BUILD_RENDER_LINE(SSE_Shaded_SP , 0, 0, 0, PIXMAP, SUBPIX, , , BG_SSE )
|
|
1237 |
BUILD_RENDER_LINE(SSE_Blended_SP , 1, 0, 0, COLOR, SUBPIX, , BG_Blended_SSE , )
|
|
1238 |
BUILD_RENDER_LINE(SSE_Blended_Opaque_SP , 1, 1, 0, COLOR, SUBPIX, BG_Blended_Opaque_SSE , , )
|
|
1239 |
BUILD_RENDER_LINE(SSE_LCD , 0, 0, 1, LCD, 0, , , )
|
|
1240 |
BUILD_RENDER_LINE(SSE_LCD_SP , 0, 0, 1, LCD, SUBPIX, , , )
|
1158 | 1241 |
#endif
|
1159 | 1242 |
|
1160 | 1243 |
#if defined(HAVE_NEON_INTRINSICS)
|
1161 | |
BUILD_RENDER_LINE(NEON_Shaded , 0, 0, PIXMAP, 0 , , , BG_NEON )
|
1162 | |
BUILD_RENDER_LINE(NEON_Blended , 1, 0, COLOR, 0 , , BG_Blended_NEON, )
|
1163 | |
BUILD_RENDER_LINE(NEON_Blended_Opaque , 1, 1, COLOR, 0 , BG_Blended_Opaque_NEON, , )
|
1164 | |
BUILD_RENDER_LINE(NEON_Solid , 0, 0, BITMAP, 0 , , , BG_NEON )
|
1165 | |
BUILD_RENDER_LINE(NEON_Shaded_SP , 0, 0, PIXMAP, SUBPIX, , , BG_NEON )
|
1166 | |
BUILD_RENDER_LINE(NEON_Blended_SP , 1, 0, COLOR, SUBPIX, , BG_Blended_NEON, )
|
1167 | |
BUILD_RENDER_LINE(NEON_Blended_Opaque_SP, 1, 1, COLOR, SUBPIX, BG_Blended_Opaque_NEON, , )
|
|
1244 |
BUILD_RENDER_LINE(NEON_Shaded , 0, 0, 0, PIXMAP, 0 , , , BG_NEON )
|
|
1245 |
BUILD_RENDER_LINE(NEON_Blended , 1, 0, 0, COLOR, 0 , , BG_Blended_NEON, )
|
|
1246 |
BUILD_RENDER_LINE(NEON_Blended_Opaque , 1, 1, 0, COLOR, 0 , BG_Blended_Opaque_NEON, , )
|
|
1247 |
BUILD_RENDER_LINE(NEON_Solid , 0, 0, 0, BITMAP, 0 , , , BG_NEON )
|
|
1248 |
BUILD_RENDER_LINE(NEON_Shaded_SP , 0, 0, 0, PIXMAP, SUBPIX, , , BG_NEON )
|
|
1249 |
BUILD_RENDER_LINE(NEON_Blended_SP , 1, 0, 0, COLOR, SUBPIX, , BG_Blended_NEON, )
|
|
1250 |
BUILD_RENDER_LINE(NEON_Blended_Opaque_SP, 1, 1, 0, COLOR, SUBPIX, BG_Blended_Opaque_NEON, , )
|
|
1251 |
BUILD_RENDER_LINE(NEON_LCD , 0, 0, 1, LCD, 0 , , , )
|
|
1252 |
BUILD_RENDER_LINE(NEON_LCD_SP , 0, 0, 1, LCD, SUBPIX, , , )
|
1168 | 1253 |
#endif
|
1169 | 1254 |
|
1170 | 1255 |
#if defined(HAVE_BLIT_GLYPH_64)
|
1171 | |
BUILD_RENDER_LINE(64_Shaded , 0, 0, PIXMAP, 0 , , , BG_64 )
|
1172 | |
BUILD_RENDER_LINE(64_Blended , 1, 0, COLOR, 0 , , BG_Blended_32 , )
|
1173 | |
BUILD_RENDER_LINE(64_Blended_Opaque , 1, 1, COLOR, 0 , BG_Blended_Opaque_32 , , )
|
1174 | |
BUILD_RENDER_LINE(64_Solid , 0, 0, BITMAP, 0 , , , BG_64 )
|
1175 | |
BUILD_RENDER_LINE(64_Shaded_SP , 0, 0, PIXMAP, SUBPIX, , , BG_64 )
|
1176 | |
BUILD_RENDER_LINE(64_Blended_SP , 1, 0, COLOR, SUBPIX, , BG_Blended_32 , )
|
1177 | |
BUILD_RENDER_LINE(64_Blended_Opaque_SP , 1, 1, COLOR, SUBPIX, BG_Blended_Opaque_32 , , )
|
|
1256 |
BUILD_RENDER_LINE(64_Shaded , 0, 0, 0, PIXMAP, 0 , , , BG_64 )
|
|
1257 |
BUILD_RENDER_LINE(64_Blended , 1, 0, 0, COLOR, 0 , , BG_Blended_32 , )
|
|
1258 |
BUILD_RENDER_LINE(64_Blended_Opaque , 1, 1, 0, COLOR, 0 , BG_Blended_Opaque_32 , , )
|
|
1259 |
BUILD_RENDER_LINE(64_Solid , 0, 0, 0, BITMAP, 0 , , , BG_64 )
|
|
1260 |
BUILD_RENDER_LINE(64_Shaded_SP , 0, 0, 0, PIXMAP, SUBPIX, , , BG_64 )
|
|
1261 |
BUILD_RENDER_LINE(64_Blended_SP , 1, 0, 0, COLOR, SUBPIX, , BG_Blended_32 , )
|
|
1262 |
BUILD_RENDER_LINE(64_Blended_Opaque_SP , 1, 1, 0, COLOR, SUBPIX, BG_Blended_Opaque_32 , , )
|
|
1263 |
BUILD_RENDER_LINE(64_LCD , 0, 0, 1, LCD, 0 , , , )
|
|
1264 |
BUILD_RENDER_LINE(64_LCD_SP , 0, 0, 1, LCD, SUBPIX, , , )
|
1178 | 1265 |
#elif defined(HAVE_BLIT_GLYPH_32)
|
1179 | |
BUILD_RENDER_LINE(32_Shaded , 0, 0, PIXMAP, 0 , , , BG_32 )
|
1180 | |
BUILD_RENDER_LINE(32_Blended , 1, 0, COLOR, 0 , , BG_Blended_32 , )
|
1181 | |
BUILD_RENDER_LINE(32_Blended_Opaque , 1, 1, COLOR, 0 , BG_Blended_Opaque_32 , , )
|
1182 | |
BUILD_RENDER_LINE(32_Solid , 0, 0, BITMAP, 0 , , , BG_32 )
|
1183 | |
BUILD_RENDER_LINE(32_Shaded_SP , 0, 0, PIXMAP, SUBPIX, , , BG_32 )
|
1184 | |
BUILD_RENDER_LINE(32_Blended_SP , 1, 0, COLOR, SUBPIX, , BG_Blended_32 , )
|
1185 | |
BUILD_RENDER_LINE(32_Blended_Opaque_SP , 1, 1, COLOR, SUBPIX, BG_Blended_Opaque_32 , , )
|
|
1266 |
BUILD_RENDER_LINE(32_Shaded , 0, 0, 0, PIXMAP, 0 , , , BG_32 )
|
|
1267 |
BUILD_RENDER_LINE(32_Blended , 1, 0, 0, COLOR, 0 , , BG_Blended_32 , )
|
|
1268 |
BUILD_RENDER_LINE(32_Blended_Opaque , 1, 1, 0, COLOR, 0 , BG_Blended_Opaque_32 , , )
|
|
1269 |
BUILD_RENDER_LINE(32_Solid , 0, 0, 0, BITMAP, 0 , , , BG_32 )
|
|
1270 |
BUILD_RENDER_LINE(32_Shaded_SP , 0, 0, 0, PIXMAP, SUBPIX, , , BG_32 )
|
|
1271 |
BUILD_RENDER_LINE(32_Blended_SP , 1, 0, 0, COLOR, SUBPIX, , BG_Blended_32 , )
|
|
1272 |
BUILD_RENDER_LINE(32_Blended_Opaque_SP , 1, 1, 0, COLOR, SUBPIX, BG_Blended_Opaque_32 , , )
|
|
1273 |
BUILD_RENDER_LINE(32_LCD , 0, 0, 1, LCD, 0 , , , )
|
|
1274 |
BUILD_RENDER_LINE(32_LCD_SP , 0, 0, 1, LCD, SUBPIX, , , )
|
1186 | 1275 |
#else
|
1187 | |
BUILD_RENDER_LINE(8_Shaded , 0, 0, PIXMAP, 0 , , , BG )
|
1188 | |
BUILD_RENDER_LINE(8_Blended , 1, 0, COLOR, 0 , , BG_Blended , )
|
1189 | |
BUILD_RENDER_LINE(8_Blended_Opaque , 1, 1, COLOR, 0 , BG_Blended_Opaque , , )
|
1190 | |
BUILD_RENDER_LINE(8_Solid , 0, 0, BITMAP, 0 , , , BG )
|
1191 | |
BUILD_RENDER_LINE(8_Shaded_SP , 0, 0, PIXMAP, SUBPIX, , , BG )
|
1192 | |
BUILD_RENDER_LINE(8_Blended_SP , 1, 0, COLOR, SUBPIX, , BG_Blended , )
|
1193 | |
BUILD_RENDER_LINE(8_Blended_Opaque_SP , 1, 1, COLOR, SUBPIX, BG_Blended_Opaque , , )
|
|
1276 |
BUILD_RENDER_LINE(8_Shaded , 0, 0, 0, PIXMAP, 0 , , , BG )
|
|
1277 |
BUILD_RENDER_LINE(8_Blended , 1, 0, 0, COLOR, 0 , , BG_Blended , )
|
|
1278 |
BUILD_RENDER_LINE(8_Blended_Opaque , 1, 1, 0, COLOR, 0 , BG_Blended_Opaque , , )
|
|
1279 |
BUILD_RENDER_LINE(8_Solid , 0, 0, 0, BITMAP, 0 , , , BG )
|
|
1280 |
BUILD_RENDER_LINE(8_Shaded_SP , 0, 0, 0, PIXMAP, SUBPIX, , , BG )
|
|
1281 |
BUILD_RENDER_LINE(8_Blended_SP , 1, 0, 0, COLOR, SUBPIX, , BG_Blended , )
|
|
1282 |
BUILD_RENDER_LINE(8_Blended_Opaque_SP , 1, 1, 0, COLOR, SUBPIX, BG_Blended_Opaque , , )
|
|
1283 |
BUILD_RENDER_LINE(8_LCD , 0, 0, 1, LCD, 0 , , , )
|
|
1284 |
BUILD_RENDER_LINE(8_LCD_SP , 0, 0, 1, LCD, SUBPIX, , , )
|
1194 | 1285 |
#endif
|
1195 | 1286 |
|
1196 | 1287 |
|
1197 | 1288 |
#if TTF_USE_SDF
|
1198 | |
static int (*Render_Line_SDF_Shaded)(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, Uint8 fg_alpha) = NULL;
|
1199 | |
BUILD_RENDER_LINE(SDF_Blended , 1, 0, COLOR, 0 , , BG_Blended_SDF , )
|
1200 | |
BUILD_RENDER_LINE(SDF_Blended_Opaque , 1, 1, COLOR, 0 , BG_Blended_Opaque_SDF , , )
|
1201 | |
static int (*Render_Line_SDF_Solid)(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, Uint8 fg_alpha) = NULL;
|
1202 | |
static int (*Render_Line_SDF_Shaded_SP)(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, Uint8 fg_alpha) = NULL;
|
1203 | |
BUILD_RENDER_LINE(SDF_Blended_SP , 1, 0, COLOR, SUBPIX, , BG_Blended_SDF , )
|
1204 | |
BUILD_RENDER_LINE(SDF_Blended_Opaque_SP , 1, 1, COLOR, SUBPIX, BG_Blended_Opaque_SDF , , )
|
|
1289 |
static int (*Render_Line_SDF_Shaded)(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, SDL_Color *fg) = NULL;
|
|
1290 |
BUILD_RENDER_LINE(SDF_Blended , 1, 0, 0, COLOR, 0 , , BG_Blended_SDF , )
|
|
1291 |
BUILD_RENDER_LINE(SDF_Blended_Opaque , 1, 1, 0, COLOR, 0 , BG_Blended_Opaque_SDF , , )
|
|
1292 |
static int (*Render_Line_SDF_Solid)(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, SDL_Color *fg) = NULL;
|
|
1293 |
static int (*Render_Line_SDF_Shaded_SP)(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, SDL_Color *fg) = NULL;
|
|
1294 |
BUILD_RENDER_LINE(SDF_Blended_SP , 1, 0, 0, COLOR, SUBPIX, , BG_Blended_SDF , )
|
|
1295 |
BUILD_RENDER_LINE(SDF_Blended_Opaque_SP , 1, 1, 0, COLOR, SUBPIX, BG_Blended_Opaque_SDF , , )
|
|
1296 |
static int (*Render_Line_SDF_LCD)(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, SDL_Color *fg) = NULL;
|
|
1297 |
static int (*Render_Line_SDF_LCD_SP)(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, SDL_Color *fg) = NULL;
|
1205 | 1298 |
#endif
|
1206 | 1299 |
|
1207 | 1300 |
#ifdef __GNUC__
|
1208 | 1301 |
#pragma GCC diagnostic pop
|
1209 | 1302 |
#endif
|
1210 | 1303 |
|
1211 | |
static SDL_INLINE int Render_Line(const render_mode_t render_mode, int subpixel, TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, Uint8 fg_alpha)
|
|
1304 |
static SDL_INLINE int Render_Line(const render_mode_t render_mode, int subpixel, TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, SDL_Color fg)
|
1212 | 1305 |
{
|
1213 | 1306 |
/* Render line (pos_buf) to textbuf at (xstart, ystart) */
|
1214 | 1307 |
|
1215 | 1308 |
/* Subpixel with RENDER_SOLID doesn't make sense. */
|
1216 | 1309 |
/* (and 'cached->subpixel.translation' would need to distinguish bitmap/pixmap). */
|
1217 | |
|
1218 | |
int is_opaque = (fg_alpha == SDL_ALPHA_OPAQUE);
|
|
1310 |
int is_opaque = (fg.a == SDL_ALPHA_OPAQUE);
|
1219 | 1311 |
|
1220 | 1312 |
#define Call_Specific_Render_Line(NAME) \
|
1221 | 1313 |
if (render_mode == RENDER_SHADED) { \
|
1222 | 1314 |
if (subpixel == 0) { \
|
1223 | |
return Render_Line_##NAME##_Shaded(font, textbuf, xstart, ystart, 0); \
|
|
1315 |
return Render_Line_##NAME##_Shaded(font, textbuf, xstart, ystart, NULL); \
|
1224 | 1316 |
} else { \
|
1225 | |
return Render_Line_##NAME##_Shaded_SP(font, textbuf, xstart, ystart, 0); \
|
|
1317 |
return Render_Line_##NAME##_Shaded_SP(font, textbuf, xstart, ystart, NULL); \
|
1226 | 1318 |
} \
|
1227 | 1319 |
} else if (render_mode == RENDER_BLENDED) { \
|
1228 | 1320 |
if (is_opaque) { \
|
1229 | 1321 |
if (subpixel == 0) { \
|
1230 | |
return Render_Line_##NAME##_Blended_Opaque(font, textbuf, xstart, ystart, 0); \
|
|
1322 |
return Render_Line_##NAME##_Blended_Opaque(font, textbuf, xstart, ystart, NULL); \
|
1231 | 1323 |
} else { \
|
1232 | |
return Render_Line_##NAME##_Blended_Opaque_SP(font, textbuf, xstart, ystart, 0); \
|
|
1324 |
return Render_Line_##NAME##_Blended_Opaque_SP(font, textbuf, xstart, ystart, NULL); \
|
1233 | 1325 |
} \
|
1234 | 1326 |
} else { \
|
1235 | 1327 |
if (subpixel == 0) { \
|
1236 | |
return Render_Line_##NAME##_Blended(font, textbuf, xstart, ystart, fg_alpha); \
|
|
1328 |
return Render_Line_##NAME##_Blended(font, textbuf, xstart, ystart, &fg); \
|
1237 | 1329 |
} else { \
|
1238 | |
return Render_Line_##NAME##_Blended_SP(font, textbuf, xstart, ystart, fg_alpha); \
|
|
1330 |
return Render_Line_##NAME##_Blended_SP(font, textbuf, xstart, ystart, &fg); \
|
1239 | 1331 |
} \
|
1240 | 1332 |
} \
|
|
1333 |
} else if (render_mode == RENDER_LCD) { \
|
|
1334 |
if (subpixel == 0) { \
|
|
1335 |
return Render_Line_##NAME##_LCD(font, textbuf, xstart, ystart, &fg); \
|
|
1336 |
} else { \
|
|
1337 |
return Render_Line_##NAME##_LCD_SP(font, textbuf, xstart, ystart, &fg); \
|
|
1338 |
} \
|
1241 | 1339 |
} else { \
|
1242 | |
return Render_Line_##NAME##_Solid(font, textbuf, xstart, ystart, 0); \
|
|
1340 |
return Render_Line_##NAME##_Solid(font, textbuf, xstart, ystart, NULL); \
|
1243 | 1341 |
}
|
1244 | 1342 |
|
1245 | 1343 |
#if TTF_USE_SDF
|
|
1479 | 1577 |
|
1480 | 1578 |
return textbuf;
|
1481 | 1579 |
}
|
|
1580 |
|
|
1581 |
static SDL_Surface* Create_Surface_LCD(int width, int height, SDL_Color fg, SDL_Color bg, Uint32 *color)
|
|
1582 |
{
|
|
1583 |
const int alignment = Get_Alignement() - 1;
|
|
1584 |
SDL_Surface *textbuf = NULL;
|
|
1585 |
Uint32 bgcolor;
|
|
1586 |
|
|
1587 |
/* Background color */
|
|
1588 |
bgcolor = (bg.a << 24) | (bg.r << 16) | (bg.g << 8) | bg.b;
|
|
1589 |
|
|
1590 |
/* Underline/Strikethrough color style */
|
|
1591 |
*color = (bg.a << 24) | (fg.r << 16) | (fg.g << 8) | fg.b;
|
|
1592 |
|
|
1593 |
/* Create the target surface if required */
|
|
1594 |
if (width != 0) {
|
|
1595 |
/* Create a surface with memory:
|
|
1596 |
* - pitch is rounded to alignment
|
|
1597 |
* - adress is aligned
|
|
1598 |
*/
|
|
1599 |
Sint64 size;
|
|
1600 |
void *pixels, *ptr;
|
|
1601 |
/* Worse case at the end of line pulling 'alignment' extra blank pixels */
|
|
1602 |
int pitch = (width + alignment) * 4;
|
|
1603 |
pitch += alignment;
|
|
1604 |
pitch &= ~alignment;
|
|
1605 |
size = height * pitch + sizeof (void *) + alignment;
|
|
1606 |
if (size < 0 || size > SDL_MAX_SINT32) {
|
|
1607 |
/* Overflow... */
|
|
1608 |
return NULL;
|
|
1609 |
}
|
|
1610 |
|
|
1611 |
ptr = SDL_malloc((size_t)size);
|
|
1612 |
if (ptr == NULL) {
|
|
1613 |
return NULL;
|
|
1614 |
}
|
|
1615 |
|
|
1616 |
/* address is aligned */
|
|
1617 |
pixels = (void *)(((size_t)ptr + sizeof(void *) + alignment) & ~alignment);
|
|
1618 |
((void **)pixels)[-1] = ptr;
|
|
1619 |
|
|
1620 |
textbuf = SDL_CreateRGBSurfaceWithFormatFrom(pixels, width, height, 0, pitch, SDL_PIXELFORMAT_ARGB8888);
|
|
1621 |
if (textbuf == NULL) {
|
|
1622 |
SDL_free(ptr);
|
|
1623 |
return NULL;
|
|
1624 |
}
|
|
1625 |
|
|
1626 |
/* Let SDL handle the memory allocation */
|
|
1627 |
textbuf->flags &= ~SDL_PREALLOC;
|
|
1628 |
textbuf->flags |= SDL_SIMD_ALIGNED;
|
|
1629 |
|
|
1630 |
/* Initialize with fg and 0 alpha */
|
|
1631 |
SDL_memset4(pixels, bgcolor, (height * pitch) / 4);
|
|
1632 |
|
|
1633 |
/* Support alpha blending */
|
|
1634 |
if (bg.a != SDL_ALPHA_OPAQUE) {
|
|
1635 |
SDL_SetSurfaceBlendMode(textbuf, SDL_BLENDMODE_BLEND);
|
|
1636 |
}
|
|
1637 |
}
|
|
1638 |
|
|
1639 |
return textbuf;
|
|
1640 |
}
|
|
1641 |
|
1482 | 1642 |
|
1483 | 1643 |
/* rcg06192001 get linked library's version. */
|
1484 | 1644 |
const SDL_version* TTF_Linked_Version(void)
|
|
1979 | 2139 |
/* Get our glyph shortcut */
|
1980 | 2140 |
slot = font->face->glyph;
|
1981 | 2141 |
|
|
2142 |
if (want & CACHED_LCD) {
|
|
2143 |
if (slot->format == FT_GLYPH_FORMAT_BITMAP) {
|
|
2144 |
TTF_SetError("LCD mode not possible with bitmap font");
|
|
2145 |
return -1;
|
|
2146 |
}
|
|
2147 |
}
|
|
2148 |
|
1982 | 2149 |
/* Get the glyph metrics, always needed */
|
1983 | 2150 |
if (cached->stored == 0) {
|
1984 | 2151 |
cached->sz_left = slot->bitmap_left;
|
|
2051 | 2218 |
if (((want & CACHED_BITMAP) && !(cached->stored & CACHED_BITMAP)) ||
|
2052 | 2219 |
((want & CACHED_PIXMAP) && !(cached->stored & CACHED_PIXMAP)) ||
|
2053 | 2220 |
((want & CACHED_COLOR) && !(cached->stored & CACHED_COLOR)) ||
|
|
2221 |
((want & CACHED_LCD) && !(cached->stored & CACHED_LCD)) ||
|
2054 | 2222 |
(want & CACHED_SUBPIX)
|
2055 | 2223 |
) {
|
2056 | 2224 |
const int mono = (want & CACHED_BITMAP);
|
|
2068 | 2236 |
ft_render_mode = FT_RENDER_MODE_SDF;
|
2069 | 2237 |
}
|
2070 | 2238 |
#endif
|
|
2239 |
if ((want & CACHED_LCD)) {
|
|
2240 |
ft_render_mode = FT_RENDER_MODE_LCD;
|
|
2241 |
}
|
2071 | 2242 |
}
|
2072 | 2243 |
|
2073 | 2244 |
/* Subpixel translation, flush previous datas */
|
|
2161 | 2332 |
dst->pitch += 3 * dst->width;
|
2162 | 2333 |
}
|
2163 | 2334 |
#endif
|
|
2335 |
if (src->pixel_mode == FT_PIXEL_MODE_LCD) {
|
|
2336 |
dst->pitch += 3 * dst->width;
|
|
2337 |
}
|
2164 | 2338 |
|
2165 | 2339 |
if (dst->rows != 0) {
|
2166 | 2340 |
unsigned int i;
|
|
2207 | 2381 |
quotient = src->width;
|
2208 | 2382 |
remainder = 0;
|
2209 | 2383 |
#endif
|
|
2384 |
} else if (src->pixel_mode == FT_PIXEL_MODE_LCD) {
|
|
2385 |
quotient = src->width / 3;
|
|
2386 |
remainder = 0;
|
2210 | 2387 |
} else {
|
2211 | 2388 |
quotient = src->width;
|
2212 | 2389 |
remainder = 0;
|
|
2333 | 2510 |
} else if (src->pixel_mode == FT_PIXEL_MODE_BGRA) {
|
2334 | 2511 |
SDL_memcpy(dstp, srcp, 4 * src->width);
|
2335 | 2512 |
#endif
|
|
2513 |
} else if (src->pixel_mode == FT_PIXEL_MODE_LCD) {
|
|
2514 |
while (quotient--) {
|
|
2515 |
Uint8 alpha = 0;
|
|
2516 |
Uint8 r, g, b;
|
|
2517 |
r = *srcp++;
|
|
2518 |
g = *srcp++;
|
|
2519 |
b = *srcp++;
|
|
2520 |
*dstp++ = b;
|
|
2521 |
*dstp++ = g;
|
|
2522 |
*dstp++ = r;
|
|
2523 |
*dstp++ = alpha;
|
|
2524 |
}
|
2336 | 2525 |
} else {
|
2337 | 2526 |
#if TTF_USE_SDF
|
2338 | 2527 |
if (ft_render_mode != FT_RENDER_MODE_SDF) {
|
|
2407 | 2596 |
/* Mark that we rendered this format */
|
2408 | 2597 |
if (mono) {
|
2409 | 2598 |
cached->stored |= CACHED_BITMAP;
|
|
2599 |
} else if (src->pixel_mode == FT_PIXEL_MODE_LCD) {
|
|
2600 |
cached->stored |= CACHED_LCD;
|
2410 | 2601 |
} else {
|
2411 | 2602 |
#if TTF_USE_COLOR
|
2412 | 2603 |
if (want & CACHED_COLOR) {
|
|
2443 | 2634 |
}
|
2444 | 2635 |
|
2445 | 2636 |
static SDL_INLINE int Find_GlyphByIndex(TTF_Font *font, FT_UInt idx,
|
2446 | |
int want_bitmap, int want_pixmap, int want_color, int want_subpixel,
|
|
2637 |
int want_bitmap, int want_pixmap, int want_color, int want_lcd, int want_subpixel,
|
2447 | 2638 |
int translation, c_glyph **out_glyph, TTF_Image **out_image)
|
2448 | 2639 |
{
|
2449 | 2640 |
/* cache size is 256, get key by masking */
|
|
2453 | 2644 |
*out_glyph = glyph;
|
2454 | 2645 |
}
|
2455 | 2646 |
|
2456 | |
if (want_pixmap || want_color) {
|
|
2647 |
if (want_pixmap || want_color || want_lcd) {
|
2457 | 2648 |
*out_image = &glyph->pixmap;
|
2458 | 2649 |
}
|
2459 | 2650 |
|
|
2466 | 2657 |
/* No a real cache, but if it always advances by integer pixels (eg translation 0 or same as previous),
|
2467 | 2658 |
* this allows to render as fast as normal mode. */
|
2468 | 2659 |
int retval;
|
2469 | |
int want = CACHED_METRICS | want_bitmap | want_pixmap | want_color | want_subpixel;
|
|
2660 |
int want = CACHED_METRICS | want_bitmap | want_pixmap | want_color | want_lcd | want_subpixel;
|
2470 | 2661 |
|
2471 | 2662 |
if (glyph->stored && glyph->index != idx) {
|
2472 | 2663 |
Flush_Glyph(glyph);
|
|
2478 | 2669 |
|
2479 | 2670 |
if ((glyph->stored & want) == want) {
|
2480 | 2671 |
return 0;
|
|
2672 |
}
|
|
2673 |
|
|
2674 |
if (want_color || want_pixmap || want_lcd) {
|
|
2675 |
if (glyph->stored & (CACHED_COLOR|CACHED_PIXMAP|CACHED_LCD)) {
|
|
2676 |
Flush_Glyph(glyph);
|
|
2677 |
}
|
2481 | 2678 |
}
|
2482 | 2679 |
|
2483 | 2680 |
glyph->index = idx;
|
|
2491 | 2688 |
else
|
2492 | 2689 |
{
|
2493 | 2690 |
int retval;
|
2494 | |
const int want = CACHED_METRICS | want_bitmap | want_pixmap | want_color;
|
|
2691 |
const int want = CACHED_METRICS | want_bitmap | want_pixmap | want_color | want_lcd;
|
2495 | 2692 |
|
2496 | 2693 |
/* Faster check as it gets inlined */
|
2497 | 2694 |
if (want_pixmap) {
|
|
2506 | 2703 |
if ((glyph->stored & CACHED_COLOR) && glyph->index == idx) {
|
2507 | 2704 |
return 0;
|
2508 | 2705 |
}
|
|
2706 |
} else if (want_lcd) {
|
|
2707 |
if ((glyph->stored & CACHED_LCD) && glyph->index == idx) {
|
|
2708 |
return 0;
|
|
2709 |
}
|
2509 | 2710 |
} else {
|
2510 | 2711 |
/* Get metrics */
|
2511 | 2712 |
if (glyph->stored && glyph->index == idx) {
|
|
2513 | 2714 |
}
|
2514 | 2715 |
}
|
2515 | 2716 |
|
2516 | |
/* Cache cannot contain both PIXMAP and COLOR (unless COLOR is actually not colored).
|
|
2717 |
/* Cache cannot contain both PIXMAP and COLOR (unless COLOR is actually not colored) and LCD
|
2517 | 2718 |
So, if it's already used, clear it */
|
2518 | |
if (want_color || want_pixmap) {
|
2519 | |
if (glyph->stored & (CACHED_COLOR|CACHED_PIXMAP)) {
|
|
2719 |
if (want_color || want_pixmap || want_lcd) {
|
|
2720 |
if (glyph->stored & (CACHED_COLOR|CACHED_PIXMAP|CACHED_LCD)) {
|
2520 | 2721 |
Flush_Glyph(glyph);
|
2521 | 2722 |
}
|
2522 | 2723 |
}
|
|
2556 | 2757 |
static SDL_INLINE int Find_GlyphMetrics(TTF_Font *font, Uint32 ch, c_glyph **out_glyph)
|
2557 | 2758 |
{
|
2558 | 2759 |
FT_UInt idx = get_char_index(font, ch);
|
2559 | |
return Find_GlyphByIndex(font, idx, 0, 0, 0, 0, 0, out_glyph, NULL);
|
|
2760 |
return Find_GlyphByIndex(font, idx, 0, 0, 0, 0, 0, 0, out_glyph, NULL);
|
2560 | 2761 |
}
|
2561 | 2762 |
|
2562 | 2763 |
void TTF_CloseFont(TTF_Font *font)
|
|
3016 | 3217 |
continue;
|
3017 | 3218 |
}
|
3018 | 3219 |
#endif
|
3019 | |
if (Find_GlyphByIndex(font, idx, 0, 0, 0, 0, 0, &glyph, NULL) < 0) {
|
|
3220 |
if (Find_GlyphByIndex(font, idx, 0, 0, 0, 0, 0, 0, &glyph, NULL) < 0) {
|
3020 | 3221 |
goto failure;
|
3021 | 3222 |
}
|
3022 | 3223 |
|
|
3209 | 3410 |
TTF_CHECK_POINTER(font, NULL);
|
3210 | 3411 |
TTF_CHECK_POINTER(text, NULL);
|
3211 | 3412 |
|
|
3413 |
if (render_mode == RENDER_LCD && !FT_IS_SCALABLE(font->face)) {
|
|
3414 |
TTF_SetError("LCD rendering is not available for non-scalable font");
|
|
3415 |
goto failure;
|
|
3416 |
}
|
|
3417 |
|
3212 | 3418 |
/* Convert input string to default encoding UTF-8 */
|
3213 | 3419 |
if (str_type == STR_TEXT) {
|
3214 | 3420 |
utf8_alloc = SDL_stack_alloc(Uint8, LATIN1_to_UTF8_len(text));
|
|
3244 | 3450 |
textbuf = Create_Surface_Solid(width, height, fg, &color);
|
3245 | 3451 |
} else if (render_mode == RENDER_SHADED) {
|
3246 | 3452 |
textbuf = Create_Surface_Shaded(width, height, fg, bg, &color);
|
3247 | |
} else { /* render_mode == RENDER_BLENDED */
|
|
3453 |
} else if (render_mode == RENDER_BLENDED) {
|
3248 | 3454 |
textbuf = Create_Surface_Blended(width, height, fg, &color);
|
|
3455 |
} else { /* render_mode == RENDER_LCD */
|
|
3456 |
textbuf = Create_Surface_LCD(width, height, fg, bg, &color);
|
3249 | 3457 |
}
|
3250 | 3458 |
|
3251 | 3459 |
if (textbuf == NULL) {
|
|
3253 | 3461 |
}
|
3254 | 3462 |
|
3255 | 3463 |
/* Render one text line to textbuf at (xstart, ystart) */
|
3256 | |
if (Render_Line(render_mode, font->render_subpixel, font, textbuf, xstart, ystart, fg.a) < 0) {
|
|
3464 |
if (Render_Line(render_mode, font->render_subpixel, font, textbuf, xstart, ystart, fg) < 0) {
|
3257 | 3465 |
goto failure;
|
3258 | 3466 |
}
|
3259 | 3467 |
|
|
3361 | 3569 |
return TTF_Render_Internal(font, (const char *)text, STR_UNICODE, fg, fg /* unused */, RENDER_BLENDED);
|
3362 | 3570 |
}
|
3363 | 3571 |
|
|
3572 |
SDL_Surface* TTF_RenderText_LCD(TTF_Font *font, const char *text, SDL_Color fg, SDL_Color bg)
|
|
3573 |
{
|
|
3574 |
return TTF_Render_Internal(font, text, STR_TEXT, fg, bg, RENDER_LCD);
|
|
3575 |
}
|
|
3576 |
|
|
3577 |
SDL_Surface* TTF_RenderUTF8_LCD(TTF_Font *font, const char *text, SDL_Color fg, SDL_Color bg)
|
|
3578 |
{
|
|
3579 |
return TTF_Render_Internal(font, text, STR_UTF8, fg, bg, RENDER_LCD);
|
|
3580 |
}
|
|
3581 |
|
|
3582 |
SDL_Surface* TTF_RenderUNICODE_LCD(TTF_Font *font, const Uint16 *text, SDL_Color fg, SDL_Color bg)
|
|
3583 |
{
|
|
3584 |
return TTF_Render_Internal(font, (const char *)text, STR_UNICODE, fg, bg, RENDER_LCD);
|
|
3585 |
}
|
|
3586 |
|
|
3587 |
SDL_Surface* TTF_RenderGlyph_LCD(TTF_Font *font, Uint16 ch, SDL_Color fg, SDL_Color bg)
|
|
3588 |
{
|
|
3589 |
return TTF_RenderGlyph32_LCD(font, ch, fg, bg);
|
|
3590 |
}
|
|
3591 |
|
|
3592 |
SDL_Surface* TTF_RenderGlyph32_LCD(TTF_Font *font, Uint32 ch, SDL_Color fg, SDL_Color bg)
|
|
3593 |
{
|
|
3594 |
Uint8 utf8[7];
|
|
3595 |
|
|
3596 |
TTF_CHECK_POINTER(font, NULL);
|
|
3597 |
|
|
3598 |
if (!Char_to_UTF8(ch, utf8)) {
|
|
3599 |
return NULL;
|
|
3600 |
}
|
|
3601 |
|
|
3602 |
return TTF_RenderUTF8_LCD(font, (char *)utf8, fg, bg);
|
|
3603 |
}
|
|
3604 |
|
3364 | 3605 |
static SDL_bool CharacterIsDelimiter(Uint32 c)
|
3365 | 3606 |
{
|
3366 | 3607 |
if (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
|
|
3391 | 3632 |
TTF_CHECK_INITIALIZED(NULL);
|
3392 | 3633 |
TTF_CHECK_POINTER(font, NULL);
|
3393 | 3634 |
TTF_CHECK_POINTER(text, NULL);
|
|
3635 |
|
|
3636 |
if (render_mode == RENDER_LCD && !FT_IS_SCALABLE(font->face)) {
|
|
3637 |
TTF_SetError("LCD rendering is not available for non-scalable font");
|
|
3638 |
goto failure;
|
|
3639 |
}
|
3394 | 3640 |
|
3395 | 3641 |
/* Convert input string to default encoding UTF-8 */
|
3396 | 3642 |
if (str_type == STR_TEXT) {
|
|
3566 | 3812 |
textbuf = Create_Surface_Solid(width, height, fg, &color);
|
3567 | 3813 |
} else if (render_mode == RENDER_SHADED) {
|
3568 | 3814 |
textbuf = Create_Surface_Shaded(width, height, fg, bg, &color);
|
3569 | |
} else { /* render_mode == RENDER_BLENDED */
|
|
3815 |
} else if (render_mode == RENDER_BLENDED) {
|
3570 | 3816 |
textbuf = Create_Surface_Blended(width, height, fg, &color);
|
|
3817 |
} else { /* render_mode == RENDER_LCD */
|
|
3818 |
textbuf = Create_Surface_LCD(width, height, fg, bg, &color);
|
3571 | 3819 |
}
|
3572 | 3820 |
|
3573 | 3821 |
if (textbuf == NULL) {
|
|
3597 | 3845 |
ystart += i * lineskip;
|
3598 | 3846 |
|
3599 | 3847 |
/* Render one text line to textbuf at (xstart, ystart) */
|
3600 | |
if (Render_Line(render_mode, font->render_subpixel, font, textbuf, xstart, ystart, fg.a) < 0) {
|
|
3848 |
if (Render_Line(render_mode, font->render_subpixel, font, textbuf, xstart, ystart, fg) < 0) {
|
3601 | 3849 |
goto failure;
|
3602 | 3850 |
}
|
3603 | 3851 |
|
|
3681 | 3929 |
SDL_Surface* TTF_RenderUNICODE_Blended_Wrapped(TTF_Font *font, const Uint16 *text, SDL_Color fg, Uint32 wrapLength)
|
3682 | 3930 |
{
|
3683 | 3931 |
return TTF_Render_Wrapped_Internal(font, (const char *)text, STR_UNICODE, fg, fg /* unused */, wrapLength, RENDER_BLENDED);
|
|
3932 |
}
|
|
3933 |
|
|
3934 |
SDL_Surface* TTF_RenderText_LCD_Wrapped(TTF_Font *font, const char *text, SDL_Color fg, SDL_Color bg, Uint32 wrapLength)
|
|
3935 |
{
|
|
3936 |
return TTF_Render_Wrapped_Internal(font, text, STR_TEXT, fg, bg, wrapLength, RENDER_LCD);
|
|
3937 |
}
|
|
3938 |
|
|
3939 |
SDL_Surface* TTF_RenderUTF8_LCD_Wrapped(TTF_Font *font, const char *text, SDL_Color fg, SDL_Color bg, Uint32 wrapLength)
|
|
3940 |
{
|
|
3941 |
return TTF_Render_Wrapped_Internal(font, text, STR_UTF8, fg, bg, wrapLength, RENDER_LCD);
|
|
3942 |
}
|
|
3943 |
|
|
3944 |
SDL_Surface* TTF_RenderUNICODE_LCD_Wrapped(TTF_Font *font, const Uint16 *text, SDL_Color fg, SDL_Color bg, Uint32 wrapLength)
|
|
3945 |
{
|
|
3946 |
return TTF_Render_Wrapped_Internal(font, (const char *)text, STR_UNICODE, fg, bg, wrapLength, RENDER_LCD);
|
3684 | 3947 |
}
|
3685 | 3948 |
|
3686 | 3949 |
SDL_Surface* TTF_RenderGlyph_Blended(TTF_Font *font, Uint16 ch, SDL_Color fg)
|