Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2. showbdf - shows a BDF font on the screen
  3. Placed in the public domain by Andre de Leiradella on 21-jan-2003.
  4.  
  5. You'll need SDL, SDLmain and SDL_gfxPrimitives to compile this program.
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <mem.h>
  11. #include <SDL.h>
  12. #include <SDL_main.h>
  13. #include "SDL_bdf.h"
  14. #include "SDL_gfxPrimitives.h"
  15.  
  16. /* Reads a byte from a rwops. */
  17. static int ReadByteRwops(void *info) {
  18.         unsigned char b;
  19.  
  20.         if (SDL_RWread((SDL_RWops *)info, &b, 1, 1) != 1)
  21.                 return -1;
  22.         return b;
  23. }
  24.  
  25. /* Put a pixel on a SDL surface. */
  26. static void PutPixel(void *surface, int x, int y, unsigned int color) {
  27.         pixelColor((SDL_Surface *)surface, (Sint16)x, (Sint16)y, (Uint32)color);
  28. }
  29.  
  30. /* Put a pixel on a b&w surface with 1 bit per pixel. The first 4 bytes hold the width of the surface. */
  31. static void PutBWPixel(void *surface, int x, int y, unsigned int color) {
  32.         (void)color;
  33.         y *= *(int *)surface;
  34.         ((unsigned char *)surface)[y + x / 8 + sizeof(int)] |= 1 << (x & 7);
  35. }
  36.  
  37. /*
  38. Example showing how to simulate anti-aliased text reducing the size of an
  39. image. This function will render a text to a new SDL_Surface.
  40. */
  41. static SDL_Surface *DrawAAH(BDF_Font *font, char *text, int entities, Uint8 r0, Uint8 g0, Uint8 b0, Uint8 r, Uint8 g, Uint8 b) {
  42.         SDL_Surface   *surface;
  43.         int           x0, y0, w, h, a;
  44.         unsigned char *pixels, *aux, *endimage, *endline;
  45.         static Uint8  alpha[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
  46.  
  47.         if (entities)
  48.                 BDF_SizeEntitiesH(font, text, &x0, &y0, &w, &h);
  49.         else
  50.                 BDF_SizeH(font, text, &x0, &y0, &w, &h);
  51. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  52.         surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, (w + 3) / 4, (h + 3) / 4, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
  53. #else
  54.         surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, (w + 3) / 4, (h + 3) / 4, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
  55. #endif
  56.         if (surface == NULL)
  57.                 return NULL;
  58.         boxRGBA(surface, 0, 0, surface->w - 1, surface->h - 1, r0, g0, b0, 255);
  59.         w = (w + 7) / 8;
  60.         h = ((h + 3) / 4) * 4;
  61.         a = w * h * + sizeof(int);
  62.         pixels = (unsigned char *)malloc(a);
  63.         if (pixels == NULL) {
  64.                 SDL_OutOfMemory();
  65.                 SDL_FreeSurface(surface);
  66.                 return NULL;
  67.         }
  68.         memset(pixels, 0, a);
  69.         *(int *)pixels = w;
  70.         if (entities)
  71.                 BDF_DrawEntitiesH(pixels, PutBWPixel, font, text, x0, y0, 0);
  72.         else
  73.                 BDF_DrawH(pixels, PutBWPixel, font, text, x0, y0, 0);
  74.         aux = pixels + sizeof(int);
  75.         endimage = aux + w * h;
  76.         for (y0 = 0; aux < endimage; y0++, aux += w * 3)
  77.                 for (endline = aux + w, x0 = 0; aux < endline; x0 += 2, aux++) {
  78.                         a = alpha[aux[0] & 15];
  79.                         a += alpha[aux[w] & 15];
  80.                         a += alpha[aux[w * 2] & 15];
  81.                         a += alpha[aux[w * 3] & 15];
  82.                         pixelRGBA(surface, x0, y0, r, g, b, a * 255 / 16);
  83.                         a = alpha[(aux[0] >> 4) & 15];
  84.                         a += alpha[(aux[w] >> 4) & 15];
  85.                         a += alpha[(aux[w * 2] >> 4) & 15];
  86.                         a += alpha[(aux[w * 3] >> 4) & 15];
  87.                         pixelRGBA(surface, x0 + 1, y0, r, g, b, a * 255 / 16);
  88.                 }
  89.         free(pixels);
  90.         return surface;
  91. }
  92.  
  93. /* Calls DrawAAH to render the text without support to entities. */
  94. static SDL_Surface *RenderAAH(BDF_Font *font, char *text, Uint8 r0, Uint8 g0, Uint8 b0, Uint8 r, Uint8 g, Uint8 b) {
  95.         return DrawAAH(font, text, 0, r0, g0, b0, r, g, b);
  96. }
  97.  
  98. /* Calls DrawAAH to render the text with support to entities. */
  99. static SDL_Surface *RenderEntitiesAAH(BDF_Font *font, char *text, Uint8 r0, Uint8 g0, Uint8 b0, Uint8 r, Uint8 g, Uint8 b) {
  100.         return DrawAAH(font, text, 1, r0, g0, b0, r, g, b);
  101. }
  102.  
  103. int main(int argc, char *argv[]) {
  104.         SDL_RWops   *rwops;
  105.         BDF_Font    *font;
  106.         SDL_Surface *screen, *aatext;
  107.         int         x0, y0, w, h;
  108.         SDL_Rect    pos;
  109.         SDL_Event   event;
  110.         char        *text = "The quick fox jumped over the lazy dog";
  111.  
  112.         if (argc != 2) {
  113.                 fprintf(stderr, "Usage: showbdf <file.bdf>\n");
  114.                 return -1;
  115.         }
  116.         /* Reads the font. */
  117.         rwops = SDL_RWFromFile(argv[1], "rb");
  118.         font = BDF_OpenFont(ReadByteRwops, (void *)rwops, &w);
  119.         SDL_RWclose(rwops);
  120.         /* Check for error code. */
  121.         switch (w) {
  122.                 case BDF_MEMORYERROR:
  123.                         fprintf(stderr, "Not enough memory reading BDF font\n");
  124.                         return -1;
  125.                 case BDF_READERROR:
  126.                         fprintf(stderr, "Error while reading BDF font\n");
  127.                         return -1;
  128.                 case BDF_WRONGVERSION:
  129.                         fprintf(stderr, "Wrong BDF font version, can only handle versions up to 2.2\n");
  130.                         return -1;
  131.                 case BDF_CANNOTHANDLEVERTICAL:
  132.                         fprintf(stderr, "Wrong BDF font direction, can only handle horizontal direction\n");
  133.                         return -1;
  134.                 case BDF_TOOMANYCHARACTERS:
  135.                 case BDF_TOOFEWCHARACTERS:
  136.                 case BDF_PARSEERROR:
  137.                         fprintf(stderr, "Invalid BDF font\n");
  138.                         return -1;
  139.         }
  140.         /* Init SDL. */
  141.         if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
  142.                 fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
  143.                 return -1;
  144.         }
  145.         atexit(SDL_Quit);
  146.         /* Check the size of the image required to acomodate the rendered text. */
  147.         BDF_SizeH(font, text, &x0, &y0, &w, &h);
  148.         /* Set the video a little bit bigger than the minimum. */
  149.         screen = SDL_SetVideoMode(w + 10, h + 15 + (h + 3) / 4, 0, SDL_SWSURFACE);
  150.         if (screen == NULL) {
  151.                 fprintf(stderr, "Couldn't set %dx%d video mode: %s\n", w + 10, h + 15 + (h + 3) / 4, SDL_GetError());
  152.                 return -1;
  153.         }
  154.         /* Clear the screen to white. */
  155.         boxColor(screen, 0, 0, screen->w - 1, screen->h - 1, 0xFFFFFFFF);
  156.         /* Render the text to the screen with black. */
  157.         BDF_DrawH((void *)screen, PutPixel, font, text, x0 + 5, y0 + 5, 0x000000FF);
  158.         /* Render the same text with white blackgorund and black foreground to a new surface. */
  159.         aatext = RenderAAH(font, text, 255, 255, 255, 0, 0, 0);
  160.         if (aatext == NULL) {
  161.                 fprintf(stderr, "Couldn't render anti-aliased text: %s\n", SDL_GetError());
  162.                 return -1;
  163.         }
  164.         /* Blit it to the screen. */
  165.         pos.x = (screen->w - aatext->w) / 2;
  166.         pos.y = h + 5 + aatext->h / 2;
  167.         SDL_BlitSurface(aatext, NULL, screen, &pos);
  168.         SDL_FreeSurface(aatext);
  169.         /* Update the screen. */
  170.         SDL_UpdateRect(screen, 0, 0, 0, 0);
  171.         /* Wait for something to happen... */
  172.         for(;;) {
  173.                 if (SDL_WaitEvent(&event) < 0) {
  174.                         fprintf(stderr, "SDL_PullEvent() error: %s\n", SDL_GetError());
  175.                         return -1;
  176.                 }
  177.                 switch (event.type) {
  178.                         case SDL_MOUSEBUTTONDOWN:
  179.                         case SDL_KEYDOWN:
  180.                         case SDL_QUIT:
  181.                                 BDF_CloseFont(font);
  182.                                 return 0;
  183.                 }
  184.         }
  185. }
  186.