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