cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

testime.c (10259B)


      1/*
      2  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
      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
     14#include <stdlib.h>
     15#include <stdio.h>
     16#include <string.h>
     17
     18#include "SDL.h"
     19#ifdef HAVE_SDL_TTF
     20#include "SDL_ttf.h"
     21#endif
     22
     23#include "SDL_test_common.h"
     24
     25#define DEFAULT_PTSIZE  30
     26#define DEFAULT_FONT    "/System/Library/Fonts/华文细黑.ttf"
     27#define MAX_TEXT_LENGTH 256
     28
     29static SDLTest_CommonState *state;
     30static SDL_Rect textRect, markedRect;
     31static SDL_Color lineColor = {0,0,0,0};
     32static SDL_Color backColor = {255,255,255,0};
     33static SDL_Color textColor = {0,0,0,0};
     34static char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
     35static int cursor = 0;
     36#ifdef HAVE_SDL_TTF
     37static TTF_Font *font;
     38#endif
     39
     40size_t utf8_length(unsigned char c)
     41{
     42    c = (unsigned char)(0xff & c);
     43    if (c < 0x80)
     44        return 1;
     45    else if ((c >> 5) ==0x6)
     46        return 2;
     47    else if ((c >> 4) == 0xe)
     48        return 3;
     49    else if ((c >> 3) == 0x1e)
     50        return 4;
     51    else
     52        return 0;
     53}
     54
     55char *utf8_next(char *p)
     56{
     57    size_t len = utf8_length(*p);
     58    size_t i = 0;
     59    if (!len)
     60        return 0;
     61
     62    for (; i < len; ++i)
     63    {
     64        ++p;
     65        if (!*p)
     66            return 0;
     67    }
     68    return p;
     69}
     70
     71char *utf8_advance(char *p, size_t distance)
     72{
     73    size_t i = 0;
     74    for (; i < distance && p; ++i)
     75    {
     76        p = utf8_next(p);
     77    }
     78    return p;
     79}
     80
     81void usage()
     82{
     83    SDL_Log("usage: testime [--font fontfile]\n");
     84    exit(0);
     85}
     86
     87void InitInput()
     88{
     89
     90    /* Prepare a rect for text input */
     91    textRect.x = textRect.y = 100;
     92    textRect.w = DEFAULT_WINDOW_WIDTH - 2 * textRect.x;
     93    textRect.h = 50;
     94
     95    text[0] = 0;
     96    markedRect = textRect;
     97    markedText[0] = 0;
     98
     99    SDL_StartTextInput();
    100}
    101
    102void CleanupVideo()
    103{
    104    SDL_StopTextInput();
    105#ifdef HAVE_SDL_TTF
    106    TTF_CloseFont(font);
    107    TTF_Quit();
    108#endif
    109}
    110
    111
    112void _Redraw(SDL_Renderer * renderer) {
    113    int w = 0, h = textRect.h;
    114    SDL_Rect cursorRect, underlineRect;
    115
    116    SDL_SetRenderDrawColor(renderer, 255,255,255,255);
    117    SDL_RenderFillRect(renderer,&textRect);
    118
    119#ifdef HAVE_SDL_TTF
    120    if (*text)
    121    {
    122        SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, text, textColor);
    123        SDL_Rect dest = {textRect.x, textRect.y, textSur->w, textSur->h };
    124
    125        SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer,textSur);
    126        SDL_FreeSurface(textSur);
    127
    128        SDL_RenderCopy(renderer,texture,NULL,&dest);
    129        SDL_DestroyTexture(texture);
    130        TTF_SizeUTF8(font, text, &w, &h);
    131    }
    132#endif
    133
    134    markedRect.x = textRect.x + w;
    135    markedRect.w = textRect.w - w;
    136    if (markedRect.w < 0)
    137    {
    138        /* Stop text input because we cannot hold any more characters */
    139        SDL_StopTextInput();
    140        return;
    141    }
    142    else
    143    {
    144        SDL_StartTextInput();
    145    }
    146
    147    cursorRect = markedRect;
    148    cursorRect.w = 2;
    149    cursorRect.h = h;
    150
    151    SDL_SetRenderDrawColor(renderer, 255,255,255,255);
    152    SDL_RenderFillRect(renderer,&markedRect);
    153
    154    if (markedText[0])
    155    {
    156#ifdef HAVE_SDL_TTF
    157        if (cursor)
    158        {
    159            char *p = utf8_advance(markedText, cursor);
    160            char c = 0;
    161            if (!p)
    162                p = &markedText[strlen(markedText)];
    163
    164            c = *p;
    165            *p = 0;
    166            TTF_SizeUTF8(font, markedText, &w, 0);
    167            cursorRect.x += w;
    168            *p = c;
    169        }
    170        SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, markedText, textColor);
    171        SDL_Rect dest = {markedRect.x, markedRect.y, textSur->w, textSur->h };
    172        TTF_SizeUTF8(font, markedText, &w, &h);
    173        SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer,textSur);
    174        SDL_FreeSurface(textSur);
    175
    176        SDL_RenderCopy(renderer,texture,NULL,&dest);
    177        SDL_DestroyTexture(texture);
    178#endif
    179
    180        underlineRect = markedRect;
    181        underlineRect.y += (h - 2);
    182        underlineRect.h = 2;
    183        underlineRect.w = w;
    184
    185        SDL_SetRenderDrawColor(renderer, 0,0,0,0);
    186        SDL_RenderFillRect(renderer,&markedRect);
    187    }
    188
    189    SDL_SetRenderDrawColor(renderer, 0,0,0,0);
    190    SDL_RenderFillRect(renderer,&cursorRect);
    191
    192    SDL_SetTextInputRect(&markedRect);
    193}
    194
    195void Redraw() {
    196    int i;
    197    for (i = 0; i < state->num_windows; ++i) {
    198        SDL_Renderer *renderer = state->renderers[i];
    199        if (state->windows[i] == NULL)
    200            continue;
    201        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
    202        SDL_RenderClear(renderer);
    203
    204        _Redraw(renderer);
    205
    206        SDL_RenderPresent(renderer);
    207    }
    208}
    209
    210int main(int argc, char *argv[]) {
    211    int i, done;
    212    SDL_Event event;
    213    const char *fontname = DEFAULT_FONT;
    214
    215    /* Enable standard application logging */
    216    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
    217
    218    /* Initialize test framework */
    219    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
    220    if (!state) {
    221        return 1;
    222    }
    223    for (i = 1; i < argc;i++) {
    224        SDLTest_CommonArg(state, i);
    225    }
    226    for (argc--, argv++; argc > 0; argc--, argv++)
    227    {
    228        if (strcmp(argv[0], "--help") == 0) {
    229            usage();
    230            return 0;
    231        }
    232
    233        else if (strcmp(argv[0], "--font") == 0)
    234        {
    235            argc--;
    236            argv++;
    237
    238            if (argc > 0)
    239                fontname = argv[0];
    240            else {
    241                usage();
    242                return 0;
    243            }
    244        }
    245    }
    246
    247    if (!SDLTest_CommonInit(state)) {
    248        return 2;
    249    }
    250
    251
    252#ifdef HAVE_SDL_TTF
    253    /* Initialize fonts */
    254    TTF_Init();
    255
    256    font = TTF_OpenFont(fontname, DEFAULT_PTSIZE);
    257    if (! font)
    258    {
    259        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to find font: %s\n", TTF_GetError());
    260        exit(-1);
    261    }
    262#endif
    263
    264    SDL_Log("Using font: %s\n", fontname);
    265    atexit(SDL_Quit);
    266
    267    InitInput();
    268    /* Create the windows and initialize the renderers */
    269    for (i = 0; i < state->num_windows; ++i) {
    270        SDL_Renderer *renderer = state->renderers[i];
    271        SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
    272        SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
    273        SDL_RenderClear(renderer);
    274    }
    275    Redraw();
    276    /* Main render loop */
    277    done = 0;
    278    while (!done) {
    279        /* Check for events */
    280        while (SDL_PollEvent(&event)) {
    281            SDLTest_CommonEvent(state, &event, &done);
    282            switch(event.type) {
    283                case SDL_KEYDOWN: {
    284                    switch (event.key.keysym.sym)
    285                    {
    286                        case SDLK_RETURN:
    287                             text[0]=0x00;
    288                             Redraw();
    289                             break;
    290                        case SDLK_BACKSPACE:
    291                             {
    292                                 int textlen=SDL_strlen(text);
    293
    294                                 do {
    295                                     if (textlen==0)
    296                                     {
    297                                         break;
    298                                     }
    299                                     if ((text[textlen-1] & 0x80) == 0x00)
    300                                     {
    301                                         /* One byte */
    302                                         text[textlen-1]=0x00;
    303                                         break;
    304                                     }
    305                                     if ((text[textlen-1] & 0xC0) == 0x80)
    306                                     {
    307                                         /* Byte from the multibyte sequence */
    308                                         text[textlen-1]=0x00;
    309                                         textlen--;
    310                                     }
    311                                     if ((text[textlen-1] & 0xC0) == 0xC0)
    312                                     {
    313                                         /* First byte of multibyte sequence */
    314                                         text[textlen-1]=0x00;
    315                                         break;
    316                                     }
    317                                 } while(1);
    318
    319                                 Redraw();
    320                             }
    321                             break;
    322                    }
    323
    324                    if (done)
    325                    {
    326                        break;
    327                    }
    328
    329                    SDL_Log("Keyboard: scancode 0x%08X = %s, keycode 0x%08X = %s\n",
    330                            event.key.keysym.scancode,
    331                            SDL_GetScancodeName(event.key.keysym.scancode),
    332                            event.key.keysym.sym, SDL_GetKeyName(event.key.keysym.sym));
    333                    break;
    334
    335                case SDL_TEXTINPUT:
    336                    if (event.text.text[0] == '\0' || event.text.text[0] == '\n' ||
    337                        markedRect.w < 0)
    338                        break;
    339
    340                    SDL_Log("Keyboard: text input \"%s\"\n", event.text.text);
    341
    342                    if (SDL_strlen(text) + SDL_strlen(event.text.text) < sizeof(text))
    343                        SDL_strlcat(text, event.text.text, sizeof(text));
    344
    345                    SDL_Log("text inputed: %s\n", text);
    346
    347                    /* After text inputed, we can clear up markedText because it */
    348                    /* is committed */
    349                    markedText[0] = 0;
    350                    Redraw();
    351                    break;
    352
    353                case SDL_TEXTEDITING:
    354                    SDL_Log("text editing \"%s\", selected range (%d, %d)\n",
    355                            event.edit.text, event.edit.start, event.edit.length);
    356
    357                    strcpy(markedText, event.edit.text);
    358                    cursor = event.edit.start;
    359                    Redraw();
    360                    break;
    361                }
    362                break;
    363
    364            }
    365        }
    366    }
    367    CleanupVideo();
    368    SDLTest_CommonQuit(state);
    369    return 0;
    370}
    371
    372
    373/* vi: set ts=4 sw=4 expandtab: */