static void TTF_SetFTError(const char *msg, FT_Error error)
{
#ifdef USE_FREETYPE_ERRORS
#undef FTERRORS_H
#define FT_ERRORDEF( e, v, s )  { e, s },
	static const struct
	{
	  int          err_code;
	  const char*  err_msg;
	} ft_errors[] = {
#include <freetype/fterrors.h>
	};
	int i;
	const char *err_msg;
	char buffer[1024];

	err_msg = NULL;
	for ( i=0; i<((sizeof ft_errors)/(sizeof ft_errors[0])); ++i ) {
		if ( error == ft_errors[i].err_code ) {
			err_msg = ft_errors[i].err_msg;
			break;
		}
	}
	if ( ! err_msg ) {
		err_msg = "unknown FreeType error";
	}
	sprintf(buffer, "%s: %s", msg, err_msg);
	TTF_SetError(buffer);
#else
	TTF_SetError(msg);
#endif /* USE_FREETYPE_ERRORS */
}
Exemplo n.º 2
0
SDL_Surface *TTF_RenderText_Solid(TTF_Font *font,
                                const char *text, SDL_Color fg)
{
        SDL_Surface *textbuf;
        Uint16 *unicode_text;
        int unicode_len;
    
        /* Copy the Latin-1 text to a UNICODE text buffer */
        unicode_len = strlen(text);
        unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text));
        if ( unicode_text == NULL ) {
                TTF_SetError("Out of memory");
                return(NULL);
        }
        ASCII_to_UNICODE(unicode_text, text, unicode_len);

	RenderUnicode(font, unicode_text, fg);
	
        /* Render the new text */
        textbuf = TTF_RenderUNICODE_Solid(font, unicode_text, fg);
    
        /* Free the text buffer and return */
        free(unicode_text);
        return(textbuf);
}
TTF_Font* TTF_OpenFontIndex( const char *file, int ptsize, long index )
{
	SDL_RWops *rw = SDL_RWFromFile(file, "rb");
	if ( rw == NULL ) {
		TTF_SetError(SDL_GetError());
		return NULL;
	}
	return TTF_OpenFontIndexRW(rw, 1, ptsize, index);
}
Exemplo n.º 4
0
TTF_Font *
TTF_OpenFontIndexRW(SDL_RWops * src, int freesrc, int ptsize, long index)
{
    TTF_Font *font;
    FT_Error error;
    FT_Face face;
    FT_Fixed scale;
    FT_Stream stream;
    int position;

    if(!TTF_initialized)
    {
        TTF_SetError("Library not initialized");
        return NULL;
    }

    /* Check to make sure we can seek in this stream */
    position = SDL_RWtell(src);
    if(position < 0)
    {
        TTF_SetError("Can't seek in stream");
        return NULL;
    }

    font = (TTF_Font *) malloc(sizeof *font);
    if(font == NULL)
    {
        TTF_SetError("Out of memory");
        return NULL;
    }
    memset(font, 0, sizeof(*font));

    font->src = src;
    font->freesrc = freesrc;

    stream = (FT_Stream) malloc(sizeof(*stream));
    if(stream == NULL)
    {
        TTF_SetError("Out of memory");
        TTF_CloseFont(font);
        return NULL;
    }
    memset(stream, 0, sizeof(*stream));

    /* 090303 Chase - Newer FT2 version sets this internally so we don't
    				have to. (Can't anyway, Don't have a definition for FT_Library)
    */
    // stream->memory = library->memory;

    stream->read = RWread;
    stream->descriptor.pointer = src;
    stream->pos = (unsigned long) position;
    SDL_RWseek(src, 0, SEEK_END);
    stream->size = (unsigned long) (SDL_RWtell(src) - position);
    SDL_RWseek(src, position, SEEK_SET);

    font->args.flags = FT_OPEN_STREAM;
    font->args.stream = stream;

    error = FT_Open_Face(library, &font->args, index, &font->face);
    if(error)
    {
        TTF_SetFTError("Couldn't load font file", error);
        TTF_CloseFont(font);
        return NULL;
    }
    face = font->face;

    /* Make sure that our font face is scalable (global metrics) */
    if(FT_IS_SCALABLE(face))
    {

        /* Set the character size and use default DPI (72) */
        error = FT_Set_Char_Size(font->face, 0, ptsize * 64, 0, 0);
        if(error)
        {
            TTF_SetFTError("Couldn't set font size", error);
            TTF_CloseFont(font);
            return NULL;
        }

        /* Get the scalable font metrics for this font */
        scale = face->size->metrics.y_scale;
        font->ascent = FT_CEIL(FT_MulFix(face->bbox.yMax, scale));
        font->descent = FT_CEIL(FT_MulFix(face->bbox.yMin, scale));
        font->height = font->ascent - font->descent + /* baseline */ 1;
        font->lineskip = FT_CEIL(FT_MulFix(face->height, scale));
        font->underline_offset =
            FT_FLOOR(FT_MulFix(face->underline_position, scale));
        font->underline_height =
            FT_FLOOR(FT_MulFix(face->underline_thickness, scale));

    }
    else
    {
        /* Non-scalable font case.  ptsize determines which family
         * or series of fonts to grab from the non-scalable format.
         * It is not the point size of the font.
         * */
        if(ptsize >= font->face->num_fixed_sizes)
            ptsize = font->face->num_fixed_sizes - 1;
        font->font_size_family = ptsize;
        error = FT_Set_Pixel_Sizes(face,
                                   face->available_sizes[ptsize].height,
                                   face->available_sizes[ptsize].width);
        /* With non-scalale fonts, Freetype2 likes to fill many of the
         * font metrics with the value of 0.  The size of the
         * non-scalable fonts must be determined differently
         * or sometimes cannot be determined.
         * */
        font->ascent = face->available_sizes[ptsize].height;
        font->descent = 0;
        font->height = face->available_sizes[ptsize].height;
        font->lineskip = FT_CEIL(font->ascent);
        font->underline_offset = FT_FLOOR(face->underline_position);
        font->underline_height = FT_FLOOR(face->underline_thickness);
    }

    if(font->underline_height < 1)
    {
        font->underline_height = 1;
    }

#ifdef DEBUG_FONTS
    printf("Font metrics:\n");
    printf("\tascent = %d, descent = %d\n", font->ascent, font->descent);
    printf("\theight = %d, lineskip = %d\n", font->height, font->lineskip);
    printf("\tunderline_offset = %d, underline_height = %d\n",
           font->underline_offset, font->underline_height);
#endif

    /* Set the default font style */
    font->style = TTF_STYLE_NORMAL;
    font->glyph_overhang = face->size->metrics.y_ppem / 10;
    /* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */
    font->glyph_italics = 0.207f;
    font->glyph_italics *= font->height;

    return font;
}
Exemplo n.º 5
0
SDL_Surface *TTF_RenderUNICODE_Solid(TTF_Font *font,
				const Uint16 *text, SDL_Color fg)
{
	int xstart, width;
	int w, h;
	SDL_Surface *textbuf;
	SDL_Palette *palette;
	const Uint16 *ch;
	Uint8 *src, *dst;
	int row, col;
	TT_Error error;

	/* Get the dimensions of the text surface */
	if ( (TTF_SizeUNICODE(font, text, &w, &h) < 0) || !w ) {
		TTF_SetError("Text has zero width");
		return(NULL);
	}

	/* Create the target surface */
	width = w;
	w = (w+7)&~7;
	textbuf = SDL_AllocSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0);
	if ( textbuf == NULL ) {
		return(NULL);
	}

	/* Fill the palette with the foreground color */
	palette = textbuf->format->palette;
	palette->colors[0].r = 255-fg.r;
	palette->colors[0].g = 255-fg.g;
	palette->colors[0].b = 255-fg.b;
	palette->colors[1].r = fg.r;
	palette->colors[1].g = fg.g;
	palette->colors[1].b = fg.b;
	SDL_SetColorKey(textbuf, SDL_SRCCOLORKEY, 0);

	/* Load and render each character */
	xstart = 0;
	for ( ch=text; *ch; ++ch ) {
		error = Find_Glyph(font, *ch);
		if ( ! error ) {
			w = font->current->bitmap.width;
			src = (Uint8 *)font->current->bitmap.bitmap;
			for ( row = 0; row < h; ++row ) {
				dst = (Uint8 *)textbuf->pixels +
				               row * textbuf->pitch +
				               xstart + font->current->minx;
				for ( col = 0; col < w; col += 8 ) {
					Uint8 c = *src++;
					*dst++ |= (c&0x80)>>7;
					c <<= 1;
					*dst++ |= (c&0x80)>>7;
					c <<= 1;
					*dst++ |= (c&0x80)>>7;
					c <<= 1;
					*dst++ |= (c&0x80)>>7;
					c <<= 1;
					*dst++ |= (c&0x80)>>7;
					c <<= 1;
					*dst++ |= (c&0x80)>>7;
					c <<= 1;
					*dst++ |= (c&0x80)>>7;
					c <<= 1;
					*dst++ |= (c&0x80)>>7;
				}
			}
			xstart += font->current->advance;
			if ( font->style & TTF_STYLE_BOLD ) {
				xstart += font->glyph_overhang;
			}
		}
	}
Exemplo n.º 6
0
TTF_Font* TTF_OpenFontIndexRW( FILE* src, int freesrc, int ptsize, long index )
{
	TTF_Font* font;
	FT_Error error;
	FT_Face face;
	FT_Fixed scale;
	FT_Stream stream;
	FT_CharMap found;
	int position, i;

	if ( ! TTF_initialized ) {
		TTF_SetError( "Library not initialized" );
		return NULL;
	}

	/* Check to make sure we can seek in this stream */
	position = ftell(src);
	if ( position < 0 ) {
		TTF_SetError( "Can't seek in stream" );
		return NULL;
	}

	font = (TTF_Font*) malloc(sizeof *font);
	if ( font == NULL ) {
		TTF_SetError( "Out of memory" );
		return NULL;
	}
	memset(font, 0, sizeof(*font));

	font->src = src;
	font->freesrc = freesrc;

	stream = (FT_Stream)malloc(sizeof(*stream));
	if ( stream == NULL ) {
		TTF_SetError( "Out of memory" );
		TTF_CloseFont( font );
		return NULL;
	}
	memset(stream, 0, sizeof(*stream));

	stream->read = ft_read;
	stream->descriptor.pointer = src;
	stream->pos = (unsigned long)position;
	fseek(src, 0, SEEK_END);
	stream->size = (unsigned long)(ftell(src) - position);
	fseek(src, position, SEEK_SET);

	font->args.flags = FT_OPEN_STREAM;
	font->args.stream = stream;

	error = FT_Open_Face( library, &font->args, index, &font->face );
	if( error ) {
		TTF_SetFTError( "Couldn't load font file", error );
		TTF_CloseFont( font );
		return NULL;
	}
	face = font->face;

	/* Set charmap for loaded font */
	found = 0;
	for (i = 0; i < face->num_charmaps; i++) {
		FT_CharMap charmap = face->charmaps[i];
/* Windows Unicode */
		if ((charmap->platform_id == 3 && charmap->encoding_id == 1) 
/* Windows Symbol */
		 || (charmap->platform_id == 3 && charmap->encoding_id == 0)
/* ISO Unicode */
		 || (charmap->platform_id == 2 && charmap->encoding_id == 1)
/* Apple Unicode */
		 || (charmap->platform_id == 0)) { 
			found = charmap;
			break;
		}
	}
	if ( found ) {
		/* If this fails, continue using the default charmap */
		FT_Set_Charmap(face, found);
	}

	/* Make sure that our font face is scalable (global metrics) */
	if ( FT_IS_SCALABLE(face) ) {

	  	/* Set the character size and use default DPI (72) */
	  	error = FT_Set_Char_Size( font->face, 0, ptsize * 64, 0, 0 );
			if( error ) {
	    	TTF_SetFTError( "Couldn't set font size", error );
	    	TTF_CloseFont( font );
	    	return NULL;
	  }

	  /* Get the scalable font metrics for this font */
	  scale = face->size->metrics.y_scale;
	  font->ascent  = FT_CEIL(FT_MulFix(face->ascender, scale));
	  font->descent = FT_CEIL(FT_MulFix(face->descender, scale));
	  font->height  = font->ascent - font->descent + /* baseline */ 1;
	  font->lineskip = FT_CEIL(FT_MulFix(face->height, scale));
	  font->underline_offset = FT_FLOOR(
			FT_MulFix(face->underline_position, scale));
	  font->underline_height = FT_FLOOR(
			FT_MulFix(face->underline_thickness, scale));

	} else {
		/* Non-scalable font case.  ptsize determines which family
		 * or series of fonts to grab from the non-scalable format.
		 * It is not the point size of the font.
		 * */
		if ( ptsize >= font->face->num_fixed_sizes )
			ptsize = font->face->num_fixed_sizes - 1;
		font->font_size_family = ptsize;
		error = FT_Set_Pixel_Sizes( face,
				face->available_sizes[ptsize].height,
				face->available_sizes[ptsize].width );
	  	/* With non-scalale fonts, Freetype2 likes to fill many of the
		 * font metrics with the value of 0.  The size of the
		 * non-scalable fonts must be determined differently
		 * or sometimes cannot be determined.
		 * */
	  	font->ascent = face->available_sizes[ptsize].height;
	  	font->descent = 0;
	  	font->height = face->available_sizes[ptsize].height;
	  	font->lineskip = FT_CEIL(font->ascent);
	  	font->underline_offset = FT_FLOOR(face->underline_position);
	  	font->underline_height = FT_FLOOR(face->underline_thickness);
	}

	if ( font->underline_height < 1 ) {
		font->underline_height = 1;
	}

#ifdef DEBUG_FONTS
	printf("Font metrics:\n");
	printf("\tascent = %d, descent = %d\n",
		font->ascent, font->descent);
	printf("\theight = %d, lineskip = %d\n",
		font->height, font->lineskip);
	printf("\tunderline_offset = %d, underline_height = %d\n",
		font->underline_offset, font->underline_height);
	printf("\tunderline_top_row = %d, strikethrough_top_row = %d\n",
		TTF_underline_top_row(font), TTF_strikethrough_top_row(font));
#endif

	/* Initialize the font face style */
	font->face_style = TTF_STYLE_NORMAL;
	if ( font->face->style_flags & FT_STYLE_FLAG_BOLD ) {
		font->face_style |= TTF_STYLE_BOLD;
	}
	if ( font->face->style_flags & FT_STYLE_FLAG_ITALIC ) {
		font->face_style |= TTF_STYLE_ITALIC;
	}
	/* Set the default font style */
	font->style = font->face_style;
	font->outline = 0;
	font->kerning = 1;
	font->glyph_overhang = face->size->metrics.y_ppem / 10;
	/* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */
	font->glyph_italics = 0.207f;
	font->glyph_italics *= font->height;

	return font;
}