slouken@5535
|
1 |
/*
|
slouken@11811
|
2 |
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
|
slouken@5535
|
3 |
|
slouken@5535
|
4 |
This software is provided 'as-is', without any express or implied
|
slouken@5535
|
5 |
warranty. In no event will the authors be held liable for any damages
|
slouken@5535
|
6 |
arising from the use of this software.
|
slouken@5535
|
7 |
|
slouken@5535
|
8 |
Permission is granted to anyone to use this software for any purpose,
|
slouken@5535
|
9 |
including commercial applications, and to alter it and redistribute it
|
slouken@5535
|
10 |
freely.
|
slouken@5535
|
11 |
*/
|
slouken@10416
|
12 |
/* A simple program to test the Input Method support in the SDL library (2.0+)
|
slouken@10416
|
13 |
If you build without SDL_ttf, you can use the GNU Unifont hex file instead.
|
slouken@10416
|
14 |
Download at http://unifoundry.com/unifont.html */
|
slouken@3338
|
15 |
|
slouken@3280
|
16 |
#include <stdlib.h>
|
slouken@3280
|
17 |
#include <stdio.h>
|
slouken@3280
|
18 |
#include <string.h>
|
slouken@3280
|
19 |
|
slouken@3280
|
20 |
#include "SDL.h"
|
slouken@3280
|
21 |
#ifdef HAVE_SDL_TTF
|
slouken@3280
|
22 |
#include "SDL_ttf.h"
|
slouken@3280
|
23 |
#endif
|
slouken@3338
|
24 |
|
slouken@6785
|
25 |
#include "SDL_test_common.h"
|
dimitris@6318
|
26 |
|
slouken@10416
|
27 |
#define DEFAULT_PTSIZE 30
|
slouken@10416
|
28 |
#ifdef HAVE_SDL_TTF
|
slouken@10416
|
29 |
#ifdef __MACOSX__
|
slouken@10416
|
30 |
#define DEFAULT_FONT "/System/Library/Fonts/华文细黑.ttf"
|
slouken@10416
|
31 |
#elif __WIN32__
|
slouken@10416
|
32 |
/* Some japanese font present on at least Windows 8.1. */
|
slouken@10416
|
33 |
#define DEFAULT_FONT "C:\\Windows\\Fonts\\yugothic.ttf"
|
slouken@10416
|
34 |
#else
|
slouken@10416
|
35 |
#define DEFAULT_FONT "NoDefaultFont.ttf"
|
slouken@10416
|
36 |
#endif
|
slouken@10416
|
37 |
#else
|
slouken@10416
|
38 |
#define DEFAULT_FONT "unifont-9.0.02.hex"
|
slouken@10416
|
39 |
#endif
|
slouken@3280
|
40 |
#define MAX_TEXT_LENGTH 256
|
slouken@3280
|
41 |
|
slouken@6785
|
42 |
static SDLTest_CommonState *state;
|
dimitris@6318
|
43 |
static SDL_Rect textRect, markedRect;
|
slouken@10416
|
44 |
static SDL_Color lineColor = {0,0,0,255};
|
philipp@10100
|
45 |
static SDL_Color backColor = {255,255,255,255};
|
slouken@10416
|
46 |
static SDL_Color textColor = {0,0,0,255};
|
dimitris@6318
|
47 |
static char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
|
dimitris@6318
|
48 |
static int cursor = 0;
|
slouken@3280
|
49 |
#ifdef HAVE_SDL_TTF
|
dimitris@6318
|
50 |
static TTF_Font *font;
|
slouken@10416
|
51 |
#else
|
slouken@10416
|
52 |
#define UNIFONT_MAX_CODEPOINT 0x1ffff
|
slouken@10416
|
53 |
#define UNIFONT_NUM_GLYPHS 0x20000
|
slouken@10416
|
54 |
/* Using 512x512 textures that are supported everywhere. */
|
slouken@10416
|
55 |
#define UNIFONT_TEXTURE_WIDTH 512
|
slouken@10416
|
56 |
#define UNIFONT_GLYPHS_IN_ROW (UNIFONT_TEXTURE_WIDTH / 16)
|
slouken@10416
|
57 |
#define UNIFONT_GLYPHS_IN_TEXTURE (UNIFONT_GLYPHS_IN_ROW * UNIFONT_GLYPHS_IN_ROW)
|
slouken@10416
|
58 |
#define UNIFONT_NUM_TEXTURES ((UNIFONT_NUM_GLYPHS + UNIFONT_GLYPHS_IN_TEXTURE - 1) / UNIFONT_GLYPHS_IN_TEXTURE)
|
slouken@10416
|
59 |
#define UNIFONT_TEXTURE_SIZE (UNIFONT_TEXTURE_WIDTH * UNIFONT_TEXTURE_WIDTH * 4)
|
slouken@10416
|
60 |
#define UNIFONT_TEXTURE_PITCH (UNIFONT_TEXTURE_WIDTH * 4)
|
slouken@10416
|
61 |
#define UNIFONT_DRAW_SCALE 2
|
slouken@10416
|
62 |
struct UnifontGlyph {
|
slouken@10416
|
63 |
Uint8 width;
|
slouken@10416
|
64 |
Uint8 data[32];
|
slouken@10416
|
65 |
} *unifontGlyph;
|
slouken@10416
|
66 |
static SDL_Texture **unifontTexture;
|
slouken@10416
|
67 |
static Uint8 unifontTextureLoaded[UNIFONT_NUM_TEXTURES] = {0};
|
slouken@10416
|
68 |
|
slouken@10416
|
69 |
/* Unifont loading code start */
|
slouken@10416
|
70 |
|
slouken@10416
|
71 |
static Uint8 dehex(char c)
|
slouken@10416
|
72 |
{
|
slouken@10416
|
73 |
if (c >= '0' && c <= '9')
|
slouken@10416
|
74 |
return c - '0';
|
slouken@10416
|
75 |
else if (c >= 'a' && c <= 'f')
|
slouken@10416
|
76 |
return c - 'a' + 10;
|
slouken@10416
|
77 |
else if (c >= 'A' && c <= 'F')
|
slouken@10416
|
78 |
return c - 'A' + 10;
|
slouken@10416
|
79 |
return 255;
|
slouken@10416
|
80 |
}
|
slouken@10416
|
81 |
|
slouken@10416
|
82 |
static Uint8 dehex2(char c1, char c2)
|
slouken@10416
|
83 |
{
|
slouken@10416
|
84 |
return (dehex(c1) << 4) | dehex(c2);
|
slouken@10416
|
85 |
}
|
slouken@10416
|
86 |
|
slouken@10416
|
87 |
static Uint8 validate_hex(const char *cp, size_t len, Uint32 *np)
|
slouken@10416
|
88 |
{
|
slouken@10416
|
89 |
Uint32 n = 0;
|
slouken@10416
|
90 |
for (; len > 0; cp++, len--)
|
slouken@10416
|
91 |
{
|
slouken@10416
|
92 |
Uint8 c = dehex(*cp);
|
slouken@10416
|
93 |
if (c == 255)
|
slouken@10416
|
94 |
return 0;
|
slouken@10416
|
95 |
n = (n << 4) | c;
|
slouken@10416
|
96 |
}
|
slouken@10416
|
97 |
if (np != NULL)
|
slouken@10416
|
98 |
*np = n;
|
slouken@10416
|
99 |
return 1;
|
slouken@10416
|
100 |
}
|
slouken@10416
|
101 |
|
slouken@11361
|
102 |
static int unifont_init(const char *fontname)
|
slouken@10416
|
103 |
{
|
slouken@10416
|
104 |
Uint8 hexBuffer[65];
|
slouken@10416
|
105 |
Uint32 numGlyphs = 0;
|
slouken@10416
|
106 |
int lineNumber = 1;
|
slouken@10416
|
107 |
size_t bytesRead;
|
slouken@10416
|
108 |
SDL_RWops *hexFile;
|
slouken@10416
|
109 |
const size_t unifontGlyphSize = UNIFONT_NUM_GLYPHS * sizeof(struct UnifontGlyph);
|
slouken@10416
|
110 |
const size_t unifontTextureSize = UNIFONT_NUM_TEXTURES * state->num_windows * sizeof(void *);
|
slouken@10416
|
111 |
|
slouken@10416
|
112 |
/* Allocate memory for the glyph data so the file can be closed after initialization. */
|
philipp@10503
|
113 |
unifontGlyph = (struct UnifontGlyph *)SDL_malloc(unifontGlyphSize);
|
slouken@10416
|
114 |
if (unifontGlyph == NULL)
|
slouken@10416
|
115 |
{
|
slouken@10416
|
116 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to allocate %d KiB for glyph data.\n", (int)(unifontGlyphSize + 1023) / 1024);
|
slouken@11361
|
117 |
return -1;
|
slouken@10416
|
118 |
}
|
slouken@10416
|
119 |
SDL_memset(unifontGlyph, 0, unifontGlyphSize);
|
slouken@10416
|
120 |
|
slouken@10416
|
121 |
/* Allocate memory for texture pointers for all renderers. */
|
philipp@10503
|
122 |
unifontTexture = (SDL_Texture **)SDL_malloc(unifontTextureSize);
|
slouken@10416
|
123 |
if (unifontTexture == NULL)
|
slouken@10416
|
124 |
{
|
slouken@10416
|
125 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to allocate %d KiB for texture pointer data.\n", (int)(unifontTextureSize + 1023) / 1024);
|
slouken@11361
|
126 |
return -1;
|
slouken@10416
|
127 |
}
|
slouken@10416
|
128 |
SDL_memset(unifontTexture, 0, unifontTextureSize);
|
slouken@10416
|
129 |
|
slouken@10416
|
130 |
hexFile = SDL_RWFromFile(fontname, "rb");
|
slouken@10416
|
131 |
if (hexFile == NULL)
|
slouken@10416
|
132 |
{
|
slouken@10416
|
133 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to open font file: %s\n", fontname);
|
slouken@11361
|
134 |
return -1;
|
slouken@10416
|
135 |
}
|
slouken@10416
|
136 |
|
slouken@10416
|
137 |
/* Read all the glyph data into memory to make it accessible later when textures are created. */
|
slouken@10416
|
138 |
do {
|
slouken@10416
|
139 |
int i, codepointHexSize;
|
slouken@10416
|
140 |
size_t bytesOverread;
|
slouken@10416
|
141 |
Uint8 glyphWidth;
|
slouken@10416
|
142 |
Uint32 codepoint;
|
slouken@10416
|
143 |
|
slouken@10416
|
144 |
bytesRead = SDL_RWread(hexFile, hexBuffer, 1, 9);
|
slouken@10416
|
145 |
if (numGlyphs > 0 && bytesRead == 0)
|
slouken@10416
|
146 |
break; /* EOF */
|
slouken@10416
|
147 |
if ((numGlyphs == 0 && bytesRead == 0) || (numGlyphs > 0 && bytesRead < 9))
|
slouken@10416
|
148 |
{
|
philipp@11133
|
149 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Unexpected end of hex file.\n");
|
slouken@11361
|
150 |
return -1;
|
slouken@10416
|
151 |
}
|
slouken@10416
|
152 |
|
slouken@10416
|
153 |
/* Looking for the colon that separates the codepoint and glyph data at position 2, 4, 6 and 8. */
|
slouken@10416
|
154 |
if (hexBuffer[2] == ':')
|
slouken@10416
|
155 |
codepointHexSize = 2;
|
slouken@10416
|
156 |
else if (hexBuffer[4] == ':')
|
slouken@10416
|
157 |
codepointHexSize = 4;
|
slouken@10416
|
158 |
else if (hexBuffer[6] == ':')
|
slouken@10416
|
159 |
codepointHexSize = 6;
|
slouken@10416
|
160 |
else if (hexBuffer[8] == ':')
|
slouken@10416
|
161 |
codepointHexSize = 8;
|
slouken@10416
|
162 |
else
|
slouken@10416
|
163 |
{
|
slouken@10416
|
164 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Could not find codepoint and glyph data separator symbol in hex file on line %d.\n", lineNumber);
|
slouken@11361
|
165 |
return -1;
|
slouken@10416
|
166 |
}
|
slouken@10416
|
167 |
|
slouken@10416
|
168 |
if (!validate_hex((const char *)hexBuffer, codepointHexSize, &codepoint))
|
slouken@10416
|
169 |
{
|
slouken@10416
|
170 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Malformed hexadecimal number in hex file on line %d.\n", lineNumber);
|
slouken@11361
|
171 |
return -1;
|
slouken@10416
|
172 |
}
|
slouken@10416
|
173 |
if (codepoint > UNIFONT_MAX_CODEPOINT)
|
slouken@10416
|
174 |
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "unifont: Codepoint on line %d exceeded limit of 0x%x.\n", lineNumber, UNIFONT_MAX_CODEPOINT);
|
slouken@10416
|
175 |
|
slouken@10416
|
176 |
/* If there was glyph data read in the last file read, move it to the front of the buffer. */
|
slouken@10416
|
177 |
bytesOverread = 8 - codepointHexSize;
|
slouken@10416
|
178 |
if (codepointHexSize < 8)
|
slouken@10416
|
179 |
SDL_memmove(hexBuffer, hexBuffer + codepointHexSize + 1, bytesOverread);
|
slouken@10416
|
180 |
bytesRead = SDL_RWread(hexFile, hexBuffer + bytesOverread, 1, 33 - bytesOverread);
|
slouken@10416
|
181 |
if (bytesRead < (33 - bytesOverread))
|
slouken@10416
|
182 |
{
|
slouken@10416
|
183 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Unexpected end of hex file.\n");
|
slouken@11361
|
184 |
return -1;
|
slouken@10416
|
185 |
}
|
slouken@10416
|
186 |
if (hexBuffer[32] == '\n')
|
slouken@10416
|
187 |
glyphWidth = 8;
|
slouken@10416
|
188 |
else
|
slouken@10416
|
189 |
{
|
slouken@10416
|
190 |
glyphWidth = 16;
|
slouken@10416
|
191 |
bytesRead = SDL_RWread(hexFile, hexBuffer + 33, 1, 32);
|
slouken@10416
|
192 |
if (bytesRead < 32)
|
slouken@10416
|
193 |
{
|
slouken@10416
|
194 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Unexpected end of hex file.\n");
|
slouken@11361
|
195 |
return -1;
|
slouken@10416
|
196 |
}
|
slouken@10416
|
197 |
}
|
slouken@10416
|
198 |
|
slouken@10416
|
199 |
if (!validate_hex((const char *)hexBuffer, glyphWidth * 4, NULL))
|
slouken@10416
|
200 |
{
|
slouken@10416
|
201 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Malformed hexadecimal glyph data in hex file on line %d.\n", lineNumber);
|
slouken@11361
|
202 |
return -1;
|
slouken@10416
|
203 |
}
|
slouken@10416
|
204 |
|
slouken@10416
|
205 |
if (codepoint <= UNIFONT_MAX_CODEPOINT)
|
slouken@10416
|
206 |
{
|
slouken@10416
|
207 |
if (unifontGlyph[codepoint].width > 0)
|
slouken@10416
|
208 |
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "unifont: Ignoring duplicate codepoint 0x%08x in hex file on line %d.\n", codepoint, lineNumber);
|
slouken@10416
|
209 |
else
|
slouken@10416
|
210 |
{
|
slouken@10416
|
211 |
unifontGlyph[codepoint].width = glyphWidth;
|
slouken@10416
|
212 |
/* Pack the hex data into a more compact form. */
|
slouken@10416
|
213 |
for (i = 0; i < glyphWidth * 2; i++)
|
slouken@10416
|
214 |
unifontGlyph[codepoint].data[i] = dehex2(hexBuffer[i * 2], hexBuffer[i * 2 + 1]);
|
slouken@10416
|
215 |
numGlyphs++;
|
slouken@10416
|
216 |
}
|
slouken@10416
|
217 |
}
|
slouken@10416
|
218 |
|
slouken@10416
|
219 |
lineNumber++;
|
slouken@10416
|
220 |
} while (bytesRead > 0);
|
slouken@10416
|
221 |
|
slouken@10416
|
222 |
SDL_RWclose(hexFile);
|
slouken@10416
|
223 |
SDL_Log("unifont: Loaded %u glyphs.\n", numGlyphs);
|
slouken@11361
|
224 |
return 0;
|
slouken@10416
|
225 |
}
|
slouken@10416
|
226 |
|
slouken@10416
|
227 |
static void unifont_make_rgba(Uint8 *src, Uint8 *dst, Uint8 width)
|
slouken@10416
|
228 |
{
|
slouken@10416
|
229 |
int i, j;
|
slouken@10416
|
230 |
Uint8 *row = dst;
|
slouken@10416
|
231 |
|
slouken@10416
|
232 |
for (i = 0; i < width * 2; i++)
|
slouken@10416
|
233 |
{
|
slouken@10416
|
234 |
Uint8 data = src[i];
|
slouken@10416
|
235 |
for (j = 0; j < 8; j++)
|
slouken@10416
|
236 |
{
|
slouken@10416
|
237 |
if (data & 0x80)
|
slouken@10416
|
238 |
{
|
slouken@10416
|
239 |
row[0] = textColor.r;
|
slouken@10416
|
240 |
row[1] = textColor.g;
|
slouken@10416
|
241 |
row[2] = textColor.b;
|
slouken@10416
|
242 |
row[3] = textColor.a;
|
slouken@10416
|
243 |
}
|
slouken@10416
|
244 |
else
|
slouken@10416
|
245 |
{
|
slouken@10416
|
246 |
row[0] = 0;
|
slouken@10416
|
247 |
row[1] = 0;
|
slouken@10416
|
248 |
row[2] = 0;
|
slouken@10416
|
249 |
row[3] = 0;
|
slouken@10416
|
250 |
}
|
slouken@10416
|
251 |
data <<= 1;
|
slouken@10416
|
252 |
row += 4;
|
slouken@10416
|
253 |
}
|
slouken@10416
|
254 |
|
slouken@10416
|
255 |
if (width == 8 || (width == 16 && i % 2 == 1))
|
slouken@10416
|
256 |
{
|
slouken@10416
|
257 |
dst += UNIFONT_TEXTURE_PITCH;
|
slouken@10416
|
258 |
row = dst;
|
slouken@10416
|
259 |
}
|
slouken@10416
|
260 |
}
|
slouken@10416
|
261 |
}
|
slouken@10416
|
262 |
|
slouken@11361
|
263 |
static int unifont_load_texture(Uint32 textureID)
|
slouken@10416
|
264 |
{
|
slouken@10416
|
265 |
int i;
|
slouken@10416
|
266 |
Uint8 * textureRGBA;
|
slouken@10416
|
267 |
|
slouken@10416
|
268 |
if (textureID >= UNIFONT_NUM_TEXTURES)
|
slouken@10416
|
269 |
{
|
slouken@10416
|
270 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Tried to load out of range texture %u.\n", textureID);
|
slouken@11361
|
271 |
return -1;
|
slouken@10416
|
272 |
}
|
slouken@10416
|
273 |
|
philipp@10503
|
274 |
textureRGBA = (Uint8 *)SDL_malloc(UNIFONT_TEXTURE_SIZE);
|
slouken@10416
|
275 |
if (textureRGBA == NULL)
|
slouken@10416
|
276 |
{
|
slouken@10416
|
277 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to allocate %d MiB for a texture.\n", UNIFONT_TEXTURE_SIZE / 1024 / 1024);
|
slouken@11361
|
278 |
return -1;
|
slouken@10416
|
279 |
}
|
slouken@10416
|
280 |
SDL_memset(textureRGBA, 0, UNIFONT_TEXTURE_SIZE);
|
slouken@10416
|
281 |
|
slouken@10416
|
282 |
/* Copy the glyphs into memory in RGBA format. */
|
slouken@10416
|
283 |
for (i = 0; i < UNIFONT_GLYPHS_IN_TEXTURE; i++)
|
slouken@10416
|
284 |
{
|
slouken@10416
|
285 |
Uint32 codepoint = UNIFONT_GLYPHS_IN_TEXTURE * textureID + i;
|
slouken@10416
|
286 |
if (unifontGlyph[codepoint].width > 0)
|
slouken@10416
|
287 |
{
|
slouken@10416
|
288 |
const Uint32 cInTex = codepoint % UNIFONT_GLYPHS_IN_TEXTURE;
|
slouken@10416
|
289 |
const size_t offset = (cInTex / UNIFONT_GLYPHS_IN_ROW) * UNIFONT_TEXTURE_PITCH * 16 + (cInTex % UNIFONT_GLYPHS_IN_ROW) * 16 * 4;
|
slouken@10416
|
290 |
unifont_make_rgba(unifontGlyph[codepoint].data, textureRGBA + offset, unifontGlyph[codepoint].width);
|
slouken@10416
|
291 |
}
|
slouken@10416
|
292 |
}
|
slouken@10416
|
293 |
|
slouken@10416
|
294 |
/* Create textures and upload the RGBA data from above. */
|
slouken@10416
|
295 |
for (i = 0; i < state->num_windows; ++i)
|
slouken@10416
|
296 |
{
|
slouken@10416
|
297 |
SDL_Renderer *renderer = state->renderers[i];
|
slouken@10416
|
298 |
SDL_Texture *tex = unifontTexture[UNIFONT_NUM_TEXTURES * i + textureID];
|
slouken@10416
|
299 |
if (state->windows[i] == NULL || renderer == NULL || tex != NULL)
|
slouken@10416
|
300 |
continue;
|
slouken@10416
|
301 |
tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, UNIFONT_TEXTURE_WIDTH, UNIFONT_TEXTURE_WIDTH);
|
slouken@10416
|
302 |
if (tex == NULL)
|
slouken@10416
|
303 |
{
|
slouken@10416
|
304 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to create texture %u for renderer %d.\n", textureID, i);
|
slouken@11361
|
305 |
return -1;
|
slouken@10416
|
306 |
}
|
slouken@10416
|
307 |
unifontTexture[UNIFONT_NUM_TEXTURES * i + textureID] = tex;
|
slouken@10416
|
308 |
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
|
slouken@10416
|
309 |
if (SDL_UpdateTexture(tex, NULL, textureRGBA, UNIFONT_TEXTURE_PITCH) != 0)
|
slouken@10416
|
310 |
{
|
slouken@10416
|
311 |
SDL_Log("unifont error: Failed to update texture %u data for renderer %d.\n", textureID, i);
|
slouken@10416
|
312 |
}
|
slouken@10416
|
313 |
}
|
slouken@10416
|
314 |
|
slouken@10416
|
315 |
SDL_free(textureRGBA);
|
slouken@10416
|
316 |
unifontTextureLoaded[textureID] = 1;
|
slouken@11361
|
317 |
return 0;
|
slouken@10416
|
318 |
}
|
slouken@10416
|
319 |
|
slouken@10416
|
320 |
static Sint32 unifont_draw_glyph(Uint32 codepoint, int rendererID, SDL_Rect *dstrect)
|
slouken@10416
|
321 |
{
|
slouken@10416
|
322 |
SDL_Texture *texture;
|
slouken@10416
|
323 |
const Uint32 textureID = codepoint / UNIFONT_GLYPHS_IN_TEXTURE;
|
slouken@10416
|
324 |
SDL_Rect srcrect;
|
slouken@10416
|
325 |
srcrect.w = srcrect.h = 16;
|
slouken@11361
|
326 |
if (codepoint > UNIFONT_MAX_CODEPOINT) {
|
slouken@10416
|
327 |
return 0;
|
slouken@11361
|
328 |
}
|
slouken@11361
|
329 |
if (!unifontTextureLoaded[textureID]) {
|
slouken@11361
|
330 |
if (unifont_load_texture(textureID) < 0) {
|
slouken@11361
|
331 |
return 0;
|
slouken@11361
|
332 |
}
|
slouken@11361
|
333 |
}
|
slouken@10416
|
334 |
texture = unifontTexture[UNIFONT_NUM_TEXTURES * rendererID + textureID];
|
slouken@10416
|
335 |
if (texture != NULL)
|
slouken@10416
|
336 |
{
|
slouken@10416
|
337 |
const Uint32 cInTex = codepoint % UNIFONT_GLYPHS_IN_TEXTURE;
|
slouken@10416
|
338 |
srcrect.x = cInTex % UNIFONT_GLYPHS_IN_ROW * 16;
|
slouken@10416
|
339 |
srcrect.y = cInTex / UNIFONT_GLYPHS_IN_ROW * 16;
|
slouken@10416
|
340 |
SDL_RenderCopy(state->renderers[rendererID], texture, &srcrect, dstrect);
|
slouken@10416
|
341 |
}
|
slouken@10416
|
342 |
return unifontGlyph[codepoint].width;
|
slouken@10416
|
343 |
}
|
slouken@10416
|
344 |
|
slouken@10416
|
345 |
static void unifont_cleanup()
|
slouken@10416
|
346 |
{
|
slouken@10416
|
347 |
int i, j;
|
slouken@10416
|
348 |
for (i = 0; i < state->num_windows; ++i)
|
slouken@10416
|
349 |
{
|
slouken@10416
|
350 |
SDL_Renderer *renderer = state->renderers[i];
|
slouken@10416
|
351 |
if (state->windows[i] == NULL || renderer == NULL)
|
slouken@10416
|
352 |
continue;
|
slouken@10416
|
353 |
for (j = 0; j < UNIFONT_NUM_TEXTURES; j++)
|
slouken@10416
|
354 |
{
|
slouken@10416
|
355 |
SDL_Texture *tex = unifontTexture[UNIFONT_NUM_TEXTURES * i + j];
|
slouken@10416
|
356 |
if (tex != NULL)
|
slouken@10416
|
357 |
SDL_DestroyTexture(tex);
|
slouken@10416
|
358 |
}
|
slouken@10416
|
359 |
}
|
slouken@10416
|
360 |
|
slouken@10416
|
361 |
for (j = 0; j < UNIFONT_NUM_TEXTURES; j++)
|
slouken@10416
|
362 |
unifontTextureLoaded[j] = 0;
|
slouken@10416
|
363 |
|
slouken@10416
|
364 |
SDL_free(unifontTexture);
|
slouken@10416
|
365 |
SDL_free(unifontGlyph);
|
slouken@10416
|
366 |
}
|
slouken@10416
|
367 |
|
slouken@10416
|
368 |
/* Unifont code end */
|
slouken@3280
|
369 |
#endif
|
dewyatt@4757
|
370 |
|
slouken@5150
|
371 |
size_t utf8_length(unsigned char c)
|
slouken@5150
|
372 |
{
|
slouken@5150
|
373 |
c = (unsigned char)(0xff & c);
|
slouken@5150
|
374 |
if (c < 0x80)
|
slouken@5150
|
375 |
return 1;
|
slouken@5150
|
376 |
else if ((c >> 5) ==0x6)
|
slouken@5150
|
377 |
return 2;
|
slouken@5150
|
378 |
else if ((c >> 4) == 0xe)
|
slouken@5150
|
379 |
return 3;
|
slouken@5150
|
380 |
else if ((c >> 3) == 0x1e)
|
slouken@5150
|
381 |
return 4;
|
slouken@5150
|
382 |
else
|
slouken@5150
|
383 |
return 0;
|
slouken@5150
|
384 |
}
|
slouken@5150
|
385 |
|
slouken@5150
|
386 |
char *utf8_next(char *p)
|
slouken@5150
|
387 |
{
|
slouken@5150
|
388 |
size_t len = utf8_length(*p);
|
slouken@5150
|
389 |
size_t i = 0;
|
slouken@5150
|
390 |
if (!len)
|
slouken@5150
|
391 |
return 0;
|
slouken@5150
|
392 |
|
slouken@5150
|
393 |
for (; i < len; ++i)
|
slouken@5150
|
394 |
{
|
slouken@5150
|
395 |
++p;
|
slouken@5150
|
396 |
if (!*p)
|
slouken@5150
|
397 |
return 0;
|
slouken@5150
|
398 |
}
|
slouken@5150
|
399 |
return p;
|
slouken@5150
|
400 |
}
|
dewyatt@4757
|
401 |
|
dewyatt@4757
|
402 |
char *utf8_advance(char *p, size_t distance)
|
dewyatt@4757
|
403 |
{
|
dewyatt@4757
|
404 |
size_t i = 0;
|
dewyatt@4757
|
405 |
for (; i < distance && p; ++i)
|
dewyatt@4757
|
406 |
{
|
dewyatt@4757
|
407 |
p = utf8_next(p);
|
dewyatt@4757
|
408 |
}
|
dewyatt@4757
|
409 |
return p;
|
dewyatt@4757
|
410 |
}
|
slouken@3280
|
411 |
|
slouken@10416
|
412 |
Uint32 utf8_decode(char *p, size_t len)
|
slouken@10416
|
413 |
{
|
slouken@10416
|
414 |
Uint32 codepoint = 0;
|
slouken@10416
|
415 |
size_t i = 0;
|
slouken@10416
|
416 |
if (!len)
|
slouken@10416
|
417 |
return 0;
|
slouken@10416
|
418 |
|
slouken@10416
|
419 |
for (; i < len; ++i)
|
slouken@10416
|
420 |
{
|
slouken@10416
|
421 |
if (i == 0)
|
slouken@10416
|
422 |
codepoint = (0xff >> len) & *p;
|
slouken@10416
|
423 |
else
|
slouken@10416
|
424 |
{
|
slouken@10416
|
425 |
codepoint <<= 6;
|
slouken@10416
|
426 |
codepoint |= 0x3f & *p;
|
slouken@10416
|
427 |
}
|
slouken@10416
|
428 |
if (!*p)
|
slouken@10416
|
429 |
return 0;
|
slouken@10416
|
430 |
p++;
|
slouken@10416
|
431 |
}
|
slouken@10416
|
432 |
|
slouken@10416
|
433 |
return codepoint;
|
slouken@10416
|
434 |
}
|
slouken@10416
|
435 |
|
slouken@3280
|
436 |
void usage()
|
slouken@3280
|
437 |
{
|
aschiffler@7639
|
438 |
SDL_Log("usage: testime [--font fontfile]\n");
|
slouken@3280
|
439 |
}
|
slouken@3280
|
440 |
|
dimitris@6318
|
441 |
void InitInput()
|
slouken@3280
|
442 |
{
|
dimitris@6318
|
443 |
/* Prepare a rect for text input */
|
dimitris@6318
|
444 |
textRect.x = textRect.y = 100;
|
dimitris@6318
|
445 |
textRect.w = DEFAULT_WINDOW_WIDTH - 2 * textRect.x;
|
dimitris@6318
|
446 |
textRect.h = 50;
|
dimitris@6318
|
447 |
|
dimitris@6318
|
448 |
text[0] = 0;
|
dimitris@6318
|
449 |
markedRect = textRect;
|
dimitris@6318
|
450 |
markedText[0] = 0;
|
dimitris@6318
|
451 |
|
dimitris@6318
|
452 |
SDL_StartTextInput();
|
dimitris@6318
|
453 |
}
|
dimitris@6318
|
454 |
|
dimitris@6318
|
455 |
void CleanupVideo()
|
dimitris@6318
|
456 |
{
|
dimitris@6318
|
457 |
SDL_StopTextInput();
|
dimitris@6318
|
458 |
#ifdef HAVE_SDL_TTF
|
dimitris@6318
|
459 |
TTF_CloseFont(font);
|
dimitris@6318
|
460 |
TTF_Quit();
|
slouken@10416
|
461 |
#else
|
slouken@10416
|
462 |
unifont_cleanup();
|
dimitris@6318
|
463 |
#endif
|
dimitris@6318
|
464 |
}
|
dimitris@6318
|
465 |
|
slouken@11361
|
466 |
void _Redraw(int rendererID)
|
slouken@11361
|
467 |
{
|
slouken@10416
|
468 |
SDL_Renderer * renderer = state->renderers[rendererID];
|
slouken@10416
|
469 |
SDL_Rect drawnTextRect, cursorRect, underlineRect;
|
slouken@10416
|
470 |
drawnTextRect = textRect;
|
slouken@10416
|
471 |
drawnTextRect.w = 0;
|
dimitris@6318
|
472 |
|
philipp@10100
|
473 |
SDL_SetRenderDrawColor(renderer, backColor.r, backColor.g, backColor.b, backColor.a);
|
dimitris@6318
|
474 |
SDL_RenderFillRect(renderer,&textRect);
|
dimitris@6318
|
475 |
|
dimitris@6318
|
476 |
if (*text)
|
dimitris@6318
|
477 |
{
|
slouken@10416
|
478 |
#ifdef HAVE_SDL_TTF
|
dimitris@6318
|
479 |
SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, text, textColor);
|
philipp@10111
|
480 |
SDL_Texture *texture;
|
slouken@10416
|
481 |
|
slouken@10416
|
482 |
/* Vertically center text */
|
slouken@10416
|
483 |
drawnTextRect.y = textRect.y + (textRect.h - textSur->h) / 2;
|
slouken@10416
|
484 |
drawnTextRect.w = textSur->w;
|
slouken@10416
|
485 |
drawnTextRect.h = textSur->h;
|
dimitris@6318
|
486 |
|
philipp@10111
|
487 |
texture = SDL_CreateTextureFromSurface(renderer,textSur);
|
dimitris@6318
|
488 |
SDL_FreeSurface(textSur);
|
dimitris@6318
|
489 |
|
slouken@10416
|
490 |
SDL_RenderCopy(renderer,texture,NULL,&drawnTextRect);
|
dimitris@6318
|
491 |
SDL_DestroyTexture(texture);
|
slouken@10416
|
492 |
#else
|
slouken@10416
|
493 |
char *utext = text;
|
slouken@10416
|
494 |
Uint32 codepoint;
|
slouken@10416
|
495 |
size_t len;
|
slouken@10416
|
496 |
SDL_Rect dstrect;
|
slouken@10416
|
497 |
|
slouken@10416
|
498 |
dstrect.x = textRect.x;
|
slouken@10416
|
499 |
dstrect.y = textRect.y + (textRect.h - 16 * UNIFONT_DRAW_SCALE) / 2;
|
slouken@10416
|
500 |
dstrect.w = 16 * UNIFONT_DRAW_SCALE;
|
slouken@10416
|
501 |
dstrect.h = 16 * UNIFONT_DRAW_SCALE;
|
slouken@10416
|
502 |
drawnTextRect.y = dstrect.y;
|
slouken@10416
|
503 |
drawnTextRect.h = dstrect.h;
|
slouken@10416
|
504 |
|
slouken@10416
|
505 |
while ((codepoint = utf8_decode(utext, len = utf8_length(*utext))))
|
slouken@10416
|
506 |
{
|
slouken@10416
|
507 |
Sint32 advance = unifont_draw_glyph(codepoint, rendererID, &dstrect) * UNIFONT_DRAW_SCALE;
|
slouken@10416
|
508 |
dstrect.x += advance;
|
slouken@10416
|
509 |
drawnTextRect.w += advance;
|
slouken@10416
|
510 |
utext += len;
|
slouken@10416
|
511 |
}
|
slouken@10416
|
512 |
#endif
|
dimitris@6318
|
513 |
}
|
dimitris@6318
|
514 |
|
slouken@10416
|
515 |
markedRect.x = textRect.x + drawnTextRect.w;
|
slouken@10416
|
516 |
markedRect.w = textRect.w - drawnTextRect.w;
|
dimitris@6318
|
517 |
if (markedRect.w < 0)
|
dimitris@6318
|
518 |
{
|
gabomdq@7663
|
519 |
/* Stop text input because we cannot hold any more characters */
|
dimitris@6318
|
520 |
SDL_StopTextInput();
|
dimitris@6318
|
521 |
return;
|
dimitris@6318
|
522 |
}
|
dimitris@6318
|
523 |
else
|
dimitris@6318
|
524 |
{
|
dimitris@6318
|
525 |
SDL_StartTextInput();
|
dimitris@6318
|
526 |
}
|
dimitris@6318
|
527 |
|
slouken@10416
|
528 |
cursorRect = drawnTextRect;
|
slouken@10416
|
529 |
cursorRect.x += cursorRect.w;
|
dimitris@6318
|
530 |
cursorRect.w = 2;
|
slouken@10416
|
531 |
cursorRect.h = drawnTextRect.h;
|
slouken@10416
|
532 |
|
slouken@10416
|
533 |
drawnTextRect.x += drawnTextRect.w;
|
slouken@10416
|
534 |
drawnTextRect.w = 0;
|
dimitris@6318
|
535 |
|
philipp@10100
|
536 |
SDL_SetRenderDrawColor(renderer, backColor.r, backColor.g, backColor.b, backColor.a);
|
dimitris@6318
|
537 |
SDL_RenderFillRect(renderer,&markedRect);
|
dimitris@6318
|
538 |
|
dimitris@6318
|
539 |
if (markedText[0])
|
dimitris@6318
|
540 |
{
|
dimitris@6318
|
541 |
#ifdef HAVE_SDL_TTF
|
philipp@10111
|
542 |
SDL_Surface *textSur;
|
philipp@10111
|
543 |
SDL_Texture *texture;
|
dimitris@6318
|
544 |
if (cursor)
|
dimitris@6318
|
545 |
{
|
dimitris@6318
|
546 |
char *p = utf8_advance(markedText, cursor);
|
dimitris@6318
|
547 |
char c = 0;
|
dimitris@6318
|
548 |
if (!p)
|
philipp@10097
|
549 |
p = &markedText[SDL_strlen(markedText)];
|
dimitris@6318
|
550 |
|
dimitris@6318
|
551 |
c = *p;
|
dimitris@6318
|
552 |
*p = 0;
|
slouken@10416
|
553 |
TTF_SizeUTF8(font, markedText, &drawnTextRect.w, NULL);
|
slouken@10416
|
554 |
cursorRect.x += drawnTextRect.w;
|
dimitris@6318
|
555 |
*p = c;
|
dimitris@6318
|
556 |
}
|
philipp@10111
|
557 |
textSur = TTF_RenderUTF8_Blended(font, markedText, textColor);
|
slouken@10416
|
558 |
/* Vertically center text */
|
slouken@10416
|
559 |
drawnTextRect.y = textRect.y + (textRect.h - textSur->h) / 2;
|
slouken@10416
|
560 |
drawnTextRect.w = textSur->w;
|
slouken@10416
|
561 |
drawnTextRect.h = textSur->h;
|
slouken@10416
|
562 |
|
philipp@10111
|
563 |
texture = SDL_CreateTextureFromSurface(renderer,textSur);
|
dimitris@6318
|
564 |
SDL_FreeSurface(textSur);
|
dimitris@6318
|
565 |
|
slouken@10416
|
566 |
SDL_RenderCopy(renderer,texture,NULL,&drawnTextRect);
|
dimitris@6318
|
567 |
SDL_DestroyTexture(texture);
|
slouken@10416
|
568 |
#else
|
slouken@10416
|
569 |
int i = 0;
|
slouken@10416
|
570 |
char *utext = markedText;
|
slouken@10416
|
571 |
Uint32 codepoint;
|
slouken@10416
|
572 |
size_t len;
|
slouken@10416
|
573 |
SDL_Rect dstrect;
|
slouken@10416
|
574 |
|
slouken@10416
|
575 |
dstrect.x = drawnTextRect.x;
|
slouken@10416
|
576 |
dstrect.y = textRect.y + (textRect.h - 16 * UNIFONT_DRAW_SCALE) / 2;
|
slouken@10416
|
577 |
dstrect.w = 16 * UNIFONT_DRAW_SCALE;
|
slouken@10416
|
578 |
dstrect.h = 16 * UNIFONT_DRAW_SCALE;
|
slouken@10416
|
579 |
drawnTextRect.y = dstrect.y;
|
slouken@10416
|
580 |
drawnTextRect.h = dstrect.h;
|
slouken@10416
|
581 |
|
slouken@10416
|
582 |
while ((codepoint = utf8_decode(utext, len = utf8_length(*utext))))
|
slouken@10416
|
583 |
{
|
slouken@10416
|
584 |
Sint32 advance = unifont_draw_glyph(codepoint, rendererID, &dstrect) * UNIFONT_DRAW_SCALE;
|
slouken@10416
|
585 |
dstrect.x += advance;
|
slouken@10416
|
586 |
drawnTextRect.w += advance;
|
slouken@10416
|
587 |
if (i < cursor)
|
slouken@10416
|
588 |
cursorRect.x += advance;
|
slouken@10416
|
589 |
i++;
|
slouken@10416
|
590 |
utext += len;
|
slouken@10416
|
591 |
}
|
dimitris@6318
|
592 |
#endif
|
dimitris@6318
|
593 |
|
slouken@10416
|
594 |
if (cursor > 0)
|
slouken@10416
|
595 |
{
|
slouken@10416
|
596 |
cursorRect.y = drawnTextRect.y;
|
slouken@10416
|
597 |
cursorRect.h = drawnTextRect.h;
|
slouken@10416
|
598 |
}
|
slouken@10416
|
599 |
|
dimitris@6318
|
600 |
underlineRect = markedRect;
|
slouken@10416
|
601 |
underlineRect.y = drawnTextRect.y + drawnTextRect.h - 2;
|
dimitris@6318
|
602 |
underlineRect.h = 2;
|
slouken@10416
|
603 |
underlineRect.w = drawnTextRect.w;
|
dimitris@6318
|
604 |
|
philipp@10100
|
605 |
SDL_SetRenderDrawColor(renderer, lineColor.r, lineColor.g, lineColor.b, lineColor.a);
|
slouken@10416
|
606 |
SDL_RenderFillRect(renderer, &underlineRect);
|
dimitris@6318
|
607 |
}
|
dimitris@6318
|
608 |
|
philipp@10100
|
609 |
SDL_SetRenderDrawColor(renderer, lineColor.r, lineColor.g, lineColor.b, lineColor.a);
|
dimitris@6318
|
610 |
SDL_RenderFillRect(renderer,&cursorRect);
|
dimitris@6318
|
611 |
|
dimitris@6318
|
612 |
SDL_SetTextInputRect(&markedRect);
|
dimitris@6318
|
613 |
}
|
dimitris@6318
|
614 |
|
slouken@11361
|
615 |
void Redraw()
|
slouken@11361
|
616 |
{
|
dimitris@6318
|
617 |
int i;
|
dimitris@6318
|
618 |
for (i = 0; i < state->num_windows; ++i) {
|
dimitris@6318
|
619 |
SDL_Renderer *renderer = state->renderers[i];
|
slouken@7787
|
620 |
if (state->windows[i] == NULL)
|
slouken@7787
|
621 |
continue;
|
dimitris@6318
|
622 |
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
dimitris@6318
|
623 |
SDL_RenderClear(renderer);
|
dimitris@6318
|
624 |
|
slouken@10416
|
625 |
/* Sending in the window id to let the font renderers know which one we're working with. */
|
slouken@10416
|
626 |
_Redraw(i);
|
dimitris@6318
|
627 |
|
dimitris@6318
|
628 |
SDL_RenderPresent(renderer);
|
dimitris@6318
|
629 |
}
|
dimitris@6318
|
630 |
}
|
dimitris@6318
|
631 |
|
slouken@11361
|
632 |
int main(int argc, char *argv[])
|
slouken@11361
|
633 |
{
|
dimitris@6318
|
634 |
int i, done;
|
dimitris@6318
|
635 |
SDL_Event event;
|
slouken@3280
|
636 |
const char *fontname = DEFAULT_FONT;
|
slouken@3280
|
637 |
|
aschiffler@7639
|
638 |
/* Enable standard application logging */
|
aschiffler@7639
|
639 |
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
aschiffler@7639
|
640 |
|
dimitris@6318
|
641 |
/* Initialize test framework */
|
slouken@6785
|
642 |
state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
|
dimitris@6318
|
643 |
if (!state) {
|
dimitris@6318
|
644 |
return 1;
|
dimitris@6318
|
645 |
}
|
dimitris@6318
|
646 |
for (i = 1; i < argc;i++) {
|
slouken@6785
|
647 |
SDLTest_CommonArg(state, i);
|
dimitris@6318
|
648 |
}
|
slouken@3280
|
649 |
for (argc--, argv++; argc > 0; argc--, argv++)
|
slouken@3280
|
650 |
{
|
dimitris@6318
|
651 |
if (strcmp(argv[0], "--help") == 0) {
|
slouken@3280
|
652 |
usage();
|
dimitris@6318
|
653 |
return 0;
|
dimitris@6318
|
654 |
}
|
slouken@3280
|
655 |
|
slouken@3280
|
656 |
else if (strcmp(argv[0], "--font") == 0)
|
slouken@3280
|
657 |
{
|
slouken@3280
|
658 |
argc--;
|
slouken@3280
|
659 |
argv++;
|
slouken@3280
|
660 |
|
slouken@3280
|
661 |
if (argc > 0)
|
slouken@3280
|
662 |
fontname = argv[0];
|
dimitris@6318
|
663 |
else {
|
slouken@3280
|
664 |
usage();
|
dimitris@6318
|
665 |
return 0;
|
dimitris@6318
|
666 |
}
|
slouken@3280
|
667 |
}
|
slouken@3280
|
668 |
}
|
slouken@7191
|
669 |
|
slouken@6785
|
670 |
if (!SDLTest_CommonInit(state)) {
|
dimitris@6318
|
671 |
return 2;
|
dimitris@6318
|
672 |
}
|
slouken@3280
|
673 |
|
slouken@3280
|
674 |
|
slouken@3280
|
675 |
#ifdef HAVE_SDL_TTF
|
slouken@3280
|
676 |
/* Initialize fonts */
|
slouken@3280
|
677 |
TTF_Init();
|
slouken@3280
|
678 |
|
slouken@3280
|
679 |
font = TTF_OpenFont(fontname, DEFAULT_PTSIZE);
|
slouken@3280
|
680 |
if (! font)
|
slouken@3280
|
681 |
{
|
aschiffler@7639
|
682 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to find font: %s\n", TTF_GetError());
|
slouken@11361
|
683 |
return -1;
|
slouken@3280
|
684 |
}
|
slouken@10416
|
685 |
#else
|
slouken@11361
|
686 |
if (unifont_init(fontname) < 0) {
|
slouken@11361
|
687 |
return -1;
|
slouken@11361
|
688 |
}
|
slouken@3280
|
689 |
#endif
|
slouken@3280
|
690 |
|
aschiffler@7639
|
691 |
SDL_Log("Using font: %s\n", fontname);
|
slouken@3280
|
692 |
|
dimitris@6318
|
693 |
InitInput();
|
dimitris@6318
|
694 |
/* Create the windows and initialize the renderers */
|
dimitris@6318
|
695 |
for (i = 0; i < state->num_windows; ++i) {
|
dimitris@6318
|
696 |
SDL_Renderer *renderer = state->renderers[i];
|
dimitris@6318
|
697 |
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
dimitris@6318
|
698 |
SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
|
dimitris@6318
|
699 |
SDL_RenderClear(renderer);
|
slouken@3280
|
700 |
}
|
slouken@7191
|
701 |
Redraw();
|
dimitris@6318
|
702 |
/* Main render loop */
|
dimitris@6318
|
703 |
done = 0;
|
dimitris@6318
|
704 |
while (!done) {
|
dimitris@6318
|
705 |
/* Check for events */
|
dimitris@6318
|
706 |
while (SDL_PollEvent(&event)) {
|
slouken@6785
|
707 |
SDLTest_CommonEvent(state, &event, &done);
|
dimitris@6318
|
708 |
switch(event.type) {
|
dimitris@6318
|
709 |
case SDL_KEYDOWN: {
|
dimitris@6318
|
710 |
switch (event.key.keysym.sym)
|
dimitris@6318
|
711 |
{
|
dimitris@6318
|
712 |
case SDLK_RETURN:
|
dimitris@6318
|
713 |
text[0]=0x00;
|
dimitris@6318
|
714 |
Redraw();
|
dimitris@6318
|
715 |
break;
|
dimitris@6318
|
716 |
case SDLK_BACKSPACE:
|
slouken@10416
|
717 |
/* Only delete text if not in editing mode. */
|
slouken@10416
|
718 |
if (!markedText[0])
|
dimitris@6318
|
719 |
{
|
philipp@9938
|
720 |
size_t textlen = SDL_strlen(text);
|
slouken@3280
|
721 |
|
dimitris@6318
|
722 |
do {
|
dimitris@6318
|
723 |
if (textlen==0)
|
dimitris@6318
|
724 |
{
|
dimitris@6318
|
725 |
break;
|
dimitris@6318
|
726 |
}
|
dimitris@6318
|
727 |
if ((text[textlen-1] & 0x80) == 0x00)
|
dimitris@6318
|
728 |
{
|
dimitris@6318
|
729 |
/* One byte */
|
dimitris@6318
|
730 |
text[textlen-1]=0x00;
|
dimitris@6318
|
731 |
break;
|
dimitris@6318
|
732 |
}
|
dimitris@6318
|
733 |
if ((text[textlen-1] & 0xC0) == 0x80)
|
dimitris@6318
|
734 |
{
|
dimitris@6318
|
735 |
/* Byte from the multibyte sequence */
|
dimitris@6318
|
736 |
text[textlen-1]=0x00;
|
dimitris@6318
|
737 |
textlen--;
|
dimitris@6318
|
738 |
}
|
dimitris@6318
|
739 |
if ((text[textlen-1] & 0xC0) == 0xC0)
|
dimitris@6318
|
740 |
{
|
dimitris@6318
|
741 |
/* First byte of multibyte sequence */
|
dimitris@6318
|
742 |
text[textlen-1]=0x00;
|
dimitris@6318
|
743 |
break;
|
dimitris@6318
|
744 |
}
|
dimitris@6318
|
745 |
} while(1);
|
dimitris@6318
|
746 |
|
dimitris@6318
|
747 |
Redraw();
|
dimitris@6318
|
748 |
}
|
dimitris@6318
|
749 |
break;
|
dimitris@6318
|
750 |
}
|
dimitris@6318
|
751 |
|
dimitris@6318
|
752 |
if (done)
|
dimitris@6318
|
753 |
{
|
dimitris@6318
|
754 |
break;
|
dimitris@6318
|
755 |
}
|
dimitris@6318
|
756 |
|
aschiffler@7639
|
757 |
SDL_Log("Keyboard: scancode 0x%08X = %s, keycode 0x%08X = %s\n",
|
dimitris@6318
|
758 |
event.key.keysym.scancode,
|
dimitris@6318
|
759 |
SDL_GetScancodeName(event.key.keysym.scancode),
|
dimitris@6318
|
760 |
event.key.keysym.sym, SDL_GetKeyName(event.key.keysym.sym));
|
dimitris@6318
|
761 |
break;
|
dimitris@6318
|
762 |
|
dimitris@6318
|
763 |
case SDL_TEXTINPUT:
|
slouken@7721
|
764 |
if (event.text.text[0] == '\0' || event.text.text[0] == '\n' ||
|
dimitris@6318
|
765 |
markedRect.w < 0)
|
dimitris@6318
|
766 |
break;
|
dimitris@6318
|
767 |
|
aschiffler@7639
|
768 |
SDL_Log("Keyboard: text input \"%s\"\n", event.text.text);
|
dimitris@6318
|
769 |
|
dimitris@6318
|
770 |
if (SDL_strlen(text) + SDL_strlen(event.text.text) < sizeof(text))
|
dimitris@6318
|
771 |
SDL_strlcat(text, event.text.text, sizeof(text));
|
dimitris@6318
|
772 |
|
aschiffler@7639
|
773 |
SDL_Log("text inputed: %s\n", text);
|
dimitris@6318
|
774 |
|
gabomdq@7663
|
775 |
/* After text inputed, we can clear up markedText because it */
|
gabomdq@7677
|
776 |
/* is committed */
|
dimitris@6318
|
777 |
markedText[0] = 0;
|
dimitris@6318
|
778 |
Redraw();
|
dimitris@6318
|
779 |
break;
|
dimitris@6318
|
780 |
|
dimitris@6318
|
781 |
case SDL_TEXTEDITING:
|
aschiffler@7639
|
782 |
SDL_Log("text editing \"%s\", selected range (%d, %d)\n",
|
dimitris@6318
|
783 |
event.edit.text, event.edit.start, event.edit.length);
|
dimitris@6318
|
784 |
|
slouken@10416
|
785 |
SDL_strlcpy(markedText, event.edit.text, SDL_TEXTEDITINGEVENT_TEXT_SIZE);
|
dimitris@6318
|
786 |
cursor = event.edit.start;
|
dimitris@6318
|
787 |
Redraw();
|
dimitris@6318
|
788 |
break;
|
dimitris@6318
|
789 |
}
|
dimitris@6318
|
790 |
break;
|
slouken@7191
|
791 |
|
dimitris@6318
|
792 |
}
|
dimitris@6318
|
793 |
}
|
slouken@3280
|
794 |
}
|
dimitris@6318
|
795 |
CleanupVideo();
|
slouken@6785
|
796 |
SDLTest_CommonQuit(state);
|
dimitris@6318
|
797 |
return 0;
|
slouken@3280
|
798 |
}
|
slouken@3280
|
799 |
|
slouken@5244
|
800 |
|
slouken@5244
|
801 |
/* vi: set ts=4 sw=4 expandtab: */
|