test/testime.c
author David Ludwig <dludwig@pobox.com>
Wed, 25 Dec 2013 21:39:48 -0500
changeset 8563 c0e68f3b6bbb
parent 7787 e6f3e8fc96ea
child 8149 681eb46b8ac4
permissions -rw-r--r--
WinRT: compiled the d3d11 renderer's shaders into SDL itself

Previously, the shaders would get compiled separately, the output of which would need to be packaged into the app. This change should make SDL's dll be the only binary needed to include SDL in a WinRT app.
     1 /*
     2   Copyright (C) 1997-2013 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 
    29 static SDLTest_CommonState *state;
    30 static SDL_Rect textRect, markedRect;
    31 static SDL_Color lineColor = {0,0,0,0};
    32 static SDL_Color backColor = {255,255,255,0};
    33 static SDL_Color textColor = {0,0,0,0};
    34 static char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
    35 static int cursor = 0;
    36 #ifdef HAVE_SDL_TTF
    37 static TTF_Font *font;
    38 #endif
    39 
    40 size_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 
    55 char *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 
    71 char *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 
    81 void usage()
    82 {
    83     SDL_Log("usage: testime [--font fontfile]\n");
    84     exit(0);
    85 }
    86 
    87 void 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 
   102 void CleanupVideo()
   103 {
   104     SDL_StopTextInput();
   105 #ifdef HAVE_SDL_TTF
   106     TTF_CloseFont(font);
   107     TTF_Quit();
   108 #endif
   109 }
   110 
   111 
   112 void _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 
   195 void 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 
   210 int 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: */