/*
*     ___                       ___
*    / _ \___ _    _____ ____  / _ \_______ __    __
*   / ___/ _ \ |/|/ / -_) __/ / // / __/ _ `/ |/|/ /
*  /_/   \___/__,__/\__/_/   /____/_/  \_,_/|__,__/
*
*
*   Original Code by John Garrison
*   Written June 25, 1999
*   To be released under the LGPL
*
*   Drawing of TrueType fonts.
*
*   See LICENSE.TXT for more LGPL info
*/

#ifdef USE_TTF

#include <stdlib.h>
#include <string.h> 

#include "SDL/SDL.h"
#include "powerdraw.h"
#include "truetype.h"


/////////////////////////////////////////////////
//          TRUETYPE READING ROUTINES          //
/////////////////////////////////////////////////

/* Open the font for displaying. This came mostly from the SDL example */
PD_TTFont *PD_TTFontInit (char *File, int Size)
{
   PD_TTFont *font;
   TT_Instance_Metrics imetrics;
   int i, n;
   short platform, encoding;
   int error;

   font = (PD_TTFont *)malloc(sizeof(*font));
   if ( font == NULL ) {
      fprintf (stderr, "Out of memory\n");
      exit(1);
   }
   memset(font, 0, sizeof(*font));

   /* Open the font and create ancillary data */
   error = TT_Open_Face(truetype, File, &font->face);
   if ( error ) {
      fprintf (stderr, "Couldn't load font file\n");
      free(font);
      exit(1);
   }
   error = TT_New_Glyph(font->face, &font->glyph);
   if ( error ) {
      fprintf (stderr, "Couldn't create glyph container\n");
      PD_DestroyTTFont(font);
      exit(1);
   }
   error = TT_New_Instance(font->face, &font->inst);
   if ( error ) {
      fprintf (stderr, "Couldn't create font instance\n");
      PD_DestroyTTFont(font);
      exit(1);
   }

   /* Set the display resolution */
   error = TT_Set_Instance_Resolutions(font->inst, 96, 96);
   if ( error ) {
      fprintf (stderr, "Couldn't set font resolution\n");
      PD_DestroyTTFont(font);
      exit(1);
   }
   error = TT_Set_Instance_CharSize(font->inst, Size*64);
   if ( error ) {
      fprintf (stderr, "Couldn't set font size\n");
      PD_DestroyTTFont(font);
      exit(1);
   }

   /* Get a Unicode mapping for this font */
   n = TT_Get_CharMap_Count(font->face);
   for ( i=0; i<n; ++i ) {
      TT_Get_CharMap_ID(font->face, i, &platform, &encoding);
      if ( ((platform == TT_PLATFORM_MICROSOFT) &&
              (encoding == TT_MS_ID_UNICODE_CS)) ||
           ((platform == TT_PLATFORM_APPLE_UNICODE) &&
              (encoding == TT_APPLE_ID_DEFAULT)) ) {
         TT_Get_CharMap(font->face, i, &font->map);
         break;
      }
   }
   if ( i == n ) {
      fprintf (stderr, "Font doesn't have a Unicode mapping\n");
      PD_DestroyTTFont(font);
      exit(1);
   }

   /* Create a scratch pixmap for this font */
   TT_Get_Instance_Metrics(font->inst, &imetrics);
   font->scratch.rows = imetrics.y_ppem + 32;
   font->scratch.width = imetrics.x_ppem + 32;
   font->scratch.flow = TT_Flow_Up;
   font->scratch.cols = (font->scratch.width+3) & -4;
   font->scratch.size = font->scratch.rows*font->scratch.cols;
   font->scratch.bitmap = malloc((int)font->scratch.size);
   if ( font->scratch.bitmap == NULL ) {
      fprintf (stderr, "Out of memory\n");
      PD_DestroyTTFont(font);
      exit(1);
   }
   return(font);
}

/* This functin contributed by Karl Bartel */
int PD_SetFontSize(PD_TTFont *Font, int Size)
{
  TT_Instance_Metrics imetrics;

  int error;

  error = TT_Set_Instance_CharSize(Font->inst, Size*64);

  /* Create a scratch pixmap for this font */
  TT_Get_Instance_Metrics(Font->inst, &imetrics);
  Font->scratch.rows = imetrics.y_ppem + 32;
  Font->scratch.width = imetrics.x_ppem + 32;
  Font->scratch.flow = TT_Flow_Up;
  Font->scratch.cols = (Font->scratch.width+3) & -4;
  Font->scratch.size = Font->scratch.rows*Font->scratch.cols;
  Font->scratch.bitmap = malloc((int)Font->scratch.size);
  if ( Font->scratch.bitmap == NULL ) {
    fprintf (stderr, "Out of memory\n");
    PD_DestroyTTFont(Font);
    exit(1);
  }

  return 0;
}

/* Returns the height of font */
int PD_GetTTFontHeight (PD_TTFont *font)
{
   int error;

   return (font->scratch.rows - 32);
   if ( error ) {
      fprintf (stderr, "Couldn't set font size\n");
      PD_DestroyTTFont(font);
      exit(1);
   }
}

/* Frees the font from memory */
int PD_DestroyTTFont (PD_TTFont *Font)
{
   TT_Close_Face(Font->face);
   if ( Font->scratch.bitmap ) {
      free(Font->scratch.bitmap);
   }
   free(Font);

   return 0;
}



/////////////////////////////////////////////////
//          TRUETYPE DRAWING ROUTINES          //
/////////////////////////////////////////////////

/* Some of this is from the SDLttf lib but I had to change it to accomodate PD_Color
also I added drawing directly to a surface and the alpha value */
int PD_DrawTTFontTextAlpha (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Color, int Alpha)
{
   char *unicode_text;
   int i, unicode_len;

   /* Copy the Latin-1 text to a UNICODE text buffer */
   unicode_len = strlen(Text);
   unicode_text = (char *)malloc((unicode_len+1)*(sizeof *unicode_text));
   if ( unicode_text == NULL ) {
      SDL_SetError("Out of memory\n");
      return(-1);
   }
   for ( i=0; i < unicode_len; ++i ) {
      unicode_text[i] = ((const unsigned char *)Text)[i];
   }
   unicode_text[i] = 0;

   /* Render the new text */
   PD_DrawTTFontTextUNICODEAlpha(Surface, Font, unicode_text, X, Y, Color, Alpha);

   /* Free the text buffer and return */
   free(unicode_text);
   return 0;
}



/* A wrapper to the function above for those who don't want to bother with alpha values
*/
int PD_DrawTTFontText (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Color)
{
   PD_DrawTTFontTextAlpha(Surface, Font, Text, X, Y, Color, 0);

   return 0;
}



int PD_DrawTTFontTextAlphaSmooth (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Fg, PD_Color Bg, int Alpha)
{
   char *unicode_text;
   int i, unicode_len;

   /* Copy the Latin-1 text to a UNICODE text buffer */
   unicode_len = strlen(Text);
   unicode_text = (char *)malloc((unicode_len+1)*(sizeof *unicode_text));
   if ( unicode_text == NULL ) {
      SDL_SetError("Out of memory\n");
      return(-1);
   }
   for ( i=0; i < unicode_len; ++i ) {
      unicode_text[i] = ((const unsigned char *)Text)[i];
   }
   unicode_text[i] = 0;

   /* Render the new text */
   PD_DrawTTFontTextUNICODEAlphaSmooth(Surface, Font, unicode_text, X, Y, Fg, Bg, Alpha);

   /* Free the text buffer and return */
   free(unicode_text);
   return 0;
}



/* A wrapper to the function above for those who don't want to bother with alpha values
*/
int PD_DrawTTFontTextSmooth (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Fg, PD_Color Bg)
{
   PD_DrawTTFontTextAlphaSmooth(Surface, Font, Text, X, Y, Fg, Bg, 0);

   return 0;
}



/* Some of this is from the SDLttf lib but I had to change it to accomodate PD_Color
also I added drawing directly to a surface and the alpha value */
int PD_DrawTTFontTextUTF8Alpha (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Color, int Alpha)
{
   char *unicode_text;
   unsigned char ch;
   int i, j, unicode_len;

   /* Copy the UTF-8 text to a UNICODE text buffer */
   unicode_len = strlen(Text);
   unicode_text = (char *)malloc((unicode_len+1)*(sizeof *unicode_text));
   if ( unicode_text == NULL ) {
      SDL_SetError("Out of memory\n");
      return -1;
   }
   for ( i=0, j=0; i < unicode_len; ++i, ++j ) {
      ch = ((const unsigned char *)Text)[i];
      if ( ch >= 0xF0 ) {
         ch  =  (char)(Text[i]&0x07) << 18;
         ch |=  (char)(Text[++i]&0x3F) << 12;
         ch |=  (char)(Text[++i]&0x3F) << 6;
         ch |=  (char)(Text[++i]&0x3F);
      } else
      if ( ch >= 0xE0 ) {
         ch  =  (char)(Text[i]&0x3F) << 12;
         ch |=  (char)(Text[++i]&0x3F) << 6;
         ch |=  (char)(Text[++i]&0x3F);
      } else
      if ( ch >= 0xC0 ) {
         ch  =  (char)(Text[i]&0x3F) << 6;
         ch |=  (char)(Text[++i]&0x3F);
      }
      unicode_text[j] = ch;
   }
   unicode_text[j] = 0;

   /* Render the new text */
   PD_DrawTTFontTextUNICODEAlpha(Surface, Font, unicode_text, X, Y, Color, PD_CreateColor(Screen, 0, 0, 0));

   /* Free the text buffer and return */
   free(unicode_text);
   return 0;
}



/* A wrapper to the function above for those who don't want to bother with alpha values
*/
int PD_DrawTTFontUTF8Text (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Color)
{
   PD_DrawTTFontTextUTF8Alpha(Surface, Font, Text, X, Y, Color, 0);

   return 0;
}



/* Some of this is from the SDLttf lib but I had to change it to accomodate PD_Color
also I added drawing directly to a surface and the alpha value */
int PD_DrawTTFontTextUTF8AlphaSmooth (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Fg, PD_Color Bg, int Alpha)
{
   char *unicode_text;
   unsigned char ch;
   int i, j, unicode_len;

   /* Copy the UTF-8 text to a UNICODE text buffer */
   unicode_len = strlen(Text);
   unicode_text = (char *)malloc((unicode_len+1)*(sizeof *unicode_text));
   if ( unicode_text == NULL ) {
      SDL_SetError("Out of memory\n");
      return -1;
   }
   for ( i=0, j=0; i < unicode_len; ++i, ++j ) {
      ch = ((const unsigned char *)Text)[i];
      if ( ch >= 0xF0 ) {
         ch  =  (char)(Text[i]&0x07) << 18;
         ch |=  (char)(Text[++i]&0x3F) << 12;
         ch |=  (char)(Text[++i]&0x3F) << 6;
         ch |=  (char)(Text[++i]&0x3F);
      } else
      if ( ch >= 0xE0 ) {
         ch  =  (char)(Text[i]&0x3F) << 12;
         ch |=  (char)(Text[++i]&0x3F) << 6;
         ch |=  (char)(Text[++i]&0x3F);
      } else
      if ( ch >= 0xC0 ) {
         ch  =  (char)(Text[i]&0x3F) << 6;
         ch |=  (char)(Text[++i]&0x3F);
      }
      unicode_text[j] = ch;
   }
   unicode_text[j] = 0;

   /* Render the new text */
   PD_DrawTTFontTextUNICODEAlphaSmooth(Surface, Font, unicode_text, X, Y, Fg, Bg, PD_CreateColor(Screen, 0, 0, 0));

   /* Free the text buffer and return */
   free(unicode_text);
   return 0;
}



/* A wrapper to the function above for those who don't want to bother with alpha values
*/
int PD_DrawTTFontUTF8TextSmooth (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Fg, PD_Color Bg)
{
   PD_DrawTTFontTextUTF8AlphaSmooth(Surface, Font, Text, X, Y, Fg, Bg, 0);

   return 0;
}



/* Some of this is from the SDLttf lib but I had to change it to accomodate PD_Color
also I added drawing directly to a surface and the alpha value */
int PD_DrawTTFontTextUNICODEAlpha(PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Color, int Alpha)
{
   PD_Surface *textbuf;
   PD_RGB fg;
   SDL_Palette *palette;
   unsigned char *ch;
   int index;
   TT_Glyph_Metrics metrics;
   TT_F26Dot6 xoff, z, minx, miny, maxx, maxy;
   int descent;
   int rdiff, gdiff, bdiff;
   Uint16 x, w, h;
   Uint8 *srcbuf;
   Uint16 srcpitch;
   Uint8 *dstbuf;
   Uint16 dstpitch;
   TT_Error error;

   /* Initialize everything to 0 */
   minx = miny = maxx = maxy = 0;

   /* Load each character and sum it's bounding box */
   xoff = 0;
   for ( ch=Text; *ch; ++ch ) {
      index = TT_Char_Index(Font->map, *ch);
      if ( ! (error=TT_Load_Glyph(Font->inst, Font->glyph, index, TTLOAD_DEFAULT)) ) {
         TT_Get_Glyph_Metrics(Font->glyph, &metrics);

         z = xoff + metrics.bbox.xMin;
         if ( minx > z )
            minx = z;

         z = xoff + metrics.bbox.xMax;
         if ( maxx < z )
            maxx = z;

         z = metrics.bbox.yMin;
         if ( miny > z )
            miny = z;

         z = metrics.bbox.yMax;
         if ( maxy < z )
            maxy = z;

         xoff += metrics.advance & -64;
      }
   }

   /* Fill the bounds rectangle */
   w = (maxx-minx)/64;
   h = (maxy-miny)/64;
   descent = -miny/64;

   /* Allocate an 8-bit pixmap */
   textbuf = PD_CreateSurfaceBPP(w, h, 8);

   fg = PD_GetRGB(Surface, Color);

   /* Fill the palette with 5 levels of shading of fg */
   palette = textbuf->format->palette;
   rdiff = fg.r - (fg.r + 5);
   gdiff = fg.g - (fg.g + 5);
   bdiff = fg.b - (fg.b + 5);

   for ( index=0; index<5; ++index ) {
      palette->colors[index].r = (fg.r + 5)+(index*rdiff)/4;
      palette->colors[index].g = (fg.g + 5)+(index*gdiff)/4;
      palette->colors[index].b = (fg.b + 5)+(index*bdiff)/4;
   }
   /* The other 3 levels are used as overflow when ORing pixels */
   for ( ; index<8; ++index ) {
      palette->colors[index] = palette->colors[4];
   }

   /* Load and render each character */
   xoff = 0;
   for ( ch=Text; *ch; ++ch ) {
      index = TT_Char_Index(Font->map, UNICODE(*ch));
      if ( ! (error=TT_Load_Glyph(Font->inst, Font->glyph, index, TTLOAD_DEFAULT)) ) {
         /* Get the bounding box and glyph pixmap */
         TT_Get_Glyph_Metrics(Font->glyph, &metrics);
         minx = metrics.bbox.xMin;
         maxx = metrics.bbox.xMax;
         miny = metrics.bbox.yMin;
         maxy = metrics.bbox.yMax;

         memset(Font->scratch.bitmap, 0, Font->scratch.size);
         TT_Get_Glyph_Pixmap(Font->glyph,
                  &Font->scratch, -minx, -miny);

         /* OR the pixmap into the text surface */
         w = (maxx-minx)/64;
         if ( w > Font->scratch.cols )
            w = Font->scratch.cols;
         if ( (xoff == 0) && minx < 0 )
            minx = 0;
         h = (maxy-miny)/64;
         if ( h > Font->scratch.rows )
            h = Font->scratch.rows;
         srcbuf = Font->scratch.bitmap;
         srcpitch = Font->scratch.cols - w;
         dstbuf = (Uint8 *)textbuf->pixels +
            (textbuf->h-descent-miny/64-1)*textbuf->pitch +
                        (xoff+minx)/64;
         dstpitch = textbuf->pitch + w;
         while ( h-- ) {
            for ( x = 0; x < w; ++x )
               *dstbuf++ |= *srcbuf++;
            srcbuf += srcpitch;
            dstbuf -= dstpitch;
         }
         xoff += metrics.advance & -64;
      }
   }
   PD_BlitTransparent(textbuf, Surface, 0, 0, X, Y, textbuf->w, textbuf->h, PD_CreateColor(Screen, 0, 0, 0), Alpha);

   /* Clean up after ourselves */
   PD_DestroySurface(textbuf);

   return 0;
}



/* A wrapper to the function above for those who don't want to bother with alpha values
*/
int PD_DrawTTFontUNICODEText (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Color)
{
   PD_DrawTTFontTextUNICODEAlpha(Surface, Font, Text, X, Y, Color, 0);

   return 0;
}



int PD_DrawTTFontTextUNICODEAlphaSmooth(PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Fg, PD_Color Bg, int Alpha)
{
   PD_Surface *textbuf;
   PD_RGB fg, bg;
   SDL_Palette *palette;
   unsigned char *ch;
   int index;
   TT_Glyph_Metrics metrics;
   TT_F26Dot6 xoff, z, minx, miny, maxx, maxy;
   int descent;
   int rdiff, gdiff, bdiff;
   Uint16 x, w, h;
   Uint8 *srcbuf;
   Uint16 srcpitch;
   Uint8 *dstbuf;
   Uint16 dstpitch;
   TT_Error error;

   /* Initialize everything to 0 */
   minx = miny = maxx = maxy = 0;

   /* Load each character and sum it's bounding box */
   xoff = 0;
   for ( ch=Text; *ch; ++ch ) {
      index = TT_Char_Index(Font->map, *ch);
      if ( ! (error=TT_Load_Glyph(Font->inst, Font->glyph, index, TTLOAD_DEFAULT)) ) {
         TT_Get_Glyph_Metrics(Font->glyph, &metrics);

         z = xoff + metrics.bbox.xMin;
         if ( minx > z )
            minx = z;

         z = xoff + metrics.bbox.xMax;
         if ( maxx < z )
            maxx = z;

         z = metrics.bbox.yMin;
         if ( miny > z )
            miny = z;

         z = metrics.bbox.yMax;
         if ( maxy < z )
            maxy = z;

         xoff += metrics.advance & -64;
      }
   }

   /* Fill the bounds rectangle */
   w = (maxx-minx)/64;
   h = (maxy-miny)/64;
   descent = -miny/64;

   /* Allocate an 8-bit pixmap */
   textbuf = PD_CreateSurfaceBPP(w, h, 8);

   fg = PD_GetRGB(Surface, Fg);
   bg = PD_GetRGB(Surface, Bg);

   /* Fill the palette with 5 levels between fg and bg*/
   palette = textbuf->format->palette;
   rdiff = fg.r - bg.r;
   gdiff = fg.g - bg.g;
   bdiff = fg.b - bg.b;

   for ( index=0; index<5; ++index ) {
      palette->colors[index].r = bg.r + (index*rdiff)/4;
      palette->colors[index].g = bg.g + (index*gdiff)/4;
      palette->colors[index].b = bg.b + (index*bdiff)/4;
   }
   /* The other 3 levels are used as overflow when ORing pixels */
   for ( ; index<8; ++index ) {
      palette->colors[index] = palette->colors[4];
   }

   /* Load and render each character */
   xoff = 0;
   for ( ch=Text; *ch; ++ch ) {
      index = TT_Char_Index(Font->map, UNICODE(*ch));
      if ( ! (error=TT_Load_Glyph(Font->inst, Font->glyph, index, TTLOAD_DEFAULT)) ) {
         /* Get the bounding box and glyph pixmap */
         TT_Get_Glyph_Metrics(Font->glyph, &metrics);
         minx = metrics.bbox.xMin;
         maxx = metrics.bbox.xMax;
         miny = metrics.bbox.yMin;
         maxy = metrics.bbox.yMax;

         memset(Font->scratch.bitmap, 0, Font->scratch.size);
         TT_Get_Glyph_Pixmap(Font->glyph,
                  &Font->scratch, -minx, -miny);

         /* OR the pixmap into the text surface */
         w = (maxx-minx)/64;
         if ( w > Font->scratch.cols )
            w = Font->scratch.cols;
         if ( (xoff == 0) && minx < 0 )
            minx = 0;
         h = (maxy-miny)/64;
         if ( h > Font->scratch.rows )
            h = Font->scratch.rows;
         srcbuf = Font->scratch.bitmap;
         srcpitch = Font->scratch.cols - w;
         dstbuf = (Uint8 *)textbuf->pixels +
            (textbuf->h-descent-miny/64-1)*textbuf->pitch +
                        (xoff+minx)/64;
         dstpitch = textbuf->pitch + w;
         while ( h-- ) {
            for ( x = 0; x < w; ++x )
               *dstbuf++ |= *srcbuf++;
            srcbuf += srcpitch;
            dstbuf -= dstpitch;
         }
         xoff += metrics.advance & -64;
      }
   }
   PD_BlitTransparent(textbuf, Surface, 0, 0, X, Y, textbuf->w, textbuf->h, PD_CreateColor(Screen, 0, 0, 0), Alpha);

   /* Clean up after ourselves */
   PD_DestroySurface(textbuf);

   return 0;
}



/* A wrapper to the function above for those who don't want to bother with alpha values
*/
int PD_DrawTTFontUNICODETextSmooth (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Fg, PD_Color Bg)
{
   PD_DrawTTFontTextUNICODEAlphaSmooth(Surface, Font, Text, X, Y, Fg, Bg, 0);

   return 0;
}



/* Taken from function above */
int PD_GetTTFTextWidth(PD_TTFont *Font, char *Text)
{
   TT_Glyph_Metrics metrics;
   TT_F26Dot6 xoff, z, minx, maxx;
   Uint16 w;
   int index;
   int error;
   unsigned char *ch;

   minx = maxx = 0;

   /* Load each character and sum it's bounding box */
   xoff = 0;
   for ( ch=Text; *ch; ++ch ) {
      index = TT_Char_Index(Font->map, *ch);
      if ( ! (error=TT_Load_Glyph(Font->inst, Font->glyph, index, TTLOAD_DEFAULT)) ) {
         TT_Get_Glyph_Metrics(Font->glyph, &metrics);
         z = xoff + metrics.bbox.xMin;
         if ( minx > z )
            minx = z;

         z = xoff + metrics.bbox.xMax;
         if ( maxx < z )
            maxx = z;

         xoff += metrics.advance & -64;
      }
   }

   /* Fill the bounds rectangle */
   w = (maxx-minx)/64;

   return w;
}

#endif



#ifndef USE_TTF
PD_TTFont *PD_TTFontInit (char *File, int Size){PD_TTFont *Dat; return Dat;}
int PD_SetFontSize(PD_TTFont *Font, int Size){return 0;}
int PD_GetTTFontHeight (PD_TTFont *Font){return 0;}
int PD_DestroyTTFont (PD_TTFont *Font){return 0;}
int PD_DrawTTFontTextAlpha (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Color, int Alpha){return 0;}
int PD_DrawTTFontText (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Color){return 0;}
int PD_DrawTTFontTextAlphaSmooth (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Fg, PD_Color Bg, int Alpha){return 0;}
int PD_DrawTTFontTextSmooth (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Fg, PD_Color Bg){return 0;}
int PD_DrawTTFontTextUTF8Alpha (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Color, int Alpha){return 0;}
int PD_DrawTTFontUTF8Text (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Color){return 0;}
int PD_DrawTTFontTextUTF8AlphaSmooth (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Fg, PD_Color Bg, int Alpha){return 0;}
int PD_DrawTTFontUTF8TextSmooth (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Fg, PD_Color Bg){return 0;}
int PD_DrawTTFontTextUNICODEAlpha(PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Color, int Alpha){return 0;}
int PD_DrawTTFontUNICODEText (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Color){return 0;}
int PD_DrawTTFontTextUNICODEAlphaSmooth(PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Fg, PD_Color Bg, int Alpha){return 0;}
int PD_DrawTTFontUNICODETextSmooth (PD_Surface *Surface, PD_TTFont *Font, char *Text, int X, int Y, PD_Color Fg, PD_Color Bg){return 0;}
int PD_GetTTFTextWidth(PD_TTFont *Font, char *Text){return 0;}
#endif