⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttf.c

📁 美化linux的kernel启动画面的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* render true type fonts to fb0  * * (w) by stepan@suse.de, code reused from SDL_ttf * */#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <freetype/freetype.h>#include <freetype/ftoutln.h>#include <freetype/ttnameid.h>#include "ttf.h"#define DEFAULT_PTSIZE  18/* FIXME: Right now we assume the gray-scale renderer Freetype is using *    supports 256 shades of gray, but we should instead key off of num_grays *       in the result FT_Bitmap after the FT_Render_Glyph() call. */#define NUM_GRAYS       256extern unsigned int fbbytes, fbx, fby, fblinelen, alpha;extern unsigned char *framebuffer;extern unsigned int fbypos, fbxpos;unsigned char *TTF_RenderUNICODE_Shaded(TTF_Font * font,					const unsigned short *text,					unsigned int fg, unsigned int bg);/* Cached glyph information */typedef struct cached_glyph {	int stored;	FT_UInt index;	FT_Bitmap bitmap;	FT_Bitmap pixmap;	int minx;	int maxx;	int miny;	int maxy;	int yoffset;	int advance;	unsigned short cached;} c_glyph;struct _TTF_Font {	/* Freetype2 maintains all sorts of useful info itself */	FT_Face face;	/* We'll cache these ourselves */	int height;	int ascent;	int descent;	int lineskip;	/* The font style */	int style;	/* Extra width in glyph bounds for text styles */	int glyph_overhang;	float glyph_italics;	/* Information in the font for underlining */	int underline_offset;	int underline_height;	/* Cache for style-transformed glyphs */	c_glyph *current;	c_glyph cache[256];	c_glyph scratch;};static void Flush_Glyph(c_glyph * glyph);static void Flush_Cache(TTF_Font * font){	int i;	int size = sizeof(font->cache) / sizeof(font->cache[0]);	for (i = 0; i < size; ++i) {		if (font->cache[i].cached) {			Flush_Glyph(&font->cache[i]);		}	}	if (font->scratch.cached) {		Flush_Glyph(&font->scratch);	}}/* character conversion *//* Macro to convert a character to a Unicode value -- assume already Unicode */#define UNICODE(c)      cstatic unsigned short *ASCII_to_UNICODE(unsigned short *unicode,					const char *text, int len){	int i;	for (i = 0; i < len; ++i) {		unicode[i] = ((const unsigned char *) text)[i];	}	unicode[i] = 0;	return unicode;}#if 0static unsigned short *UTF8_to_UNICODE(unsigned short *unicode,				       const char *utf8, int len){	int i, j;	unsigned short ch;	for (i = 0, j = 0; i < len; ++i, ++j) {		ch = ((const unsigned char *) utf8)[i];		if (ch >= 0xF0) {			ch = (unsigned short) (utf8[i] & 0x07) << 18;			ch |= (unsigned short) (utf8[++i] & 0x3F) << 12;			ch |= (unsigned short) (utf8[++i] & 0x3F) << 6;			ch |= (unsigned short) (utf8[++i] & 0x3F);		} else if (ch >= 0xE0) {			ch = (unsigned short) (utf8[i] & 0x3F) << 12;			ch |= (unsigned short) (utf8[++i] & 0x3F) << 6;			ch |= (unsigned short) (utf8[++i] & 0x3F);		} else if (ch >= 0xC0) {			ch = (unsigned short) (utf8[i] & 0x3F) << 6;			ch |= (unsigned short) (utf8[++i] & 0x3F);		}		unicode[j] = ch;	}	unicode[j] = 0;	return unicode;}#endif/* TTF stuff */static FT_Library library;static int TTF_initialized = 0;int TTF_Init(void){	int status;	FT_Error error;	status = 0;	error = FT_Init_FreeType(&library);	if (error) {		fprintf(stderr, "Couldn't init FreeType engine %d\n",			error);		status = -1;	} else {		TTF_initialized = 1;	}	return status;}void TTF_Quit(void){	if (TTF_initialized) {		FT_Done_FreeType(library);	}	TTF_initialized = 0;}#if 0SDL_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);}#endifunsigned char *TTF_RenderText_Shaded(TTF_Font * font, const char *text,				     unsigned int fg, unsigned int bg){	unsigned char *textbuf;	unsigned short *unicode_text;	int unicode_len;	/* Copy the Latin-1 text to a UNICODE text buffer */	unicode_len = strlen(text);	unicode_text =	    (unsigned short *) malloc((unicode_len + 1) *				      (sizeof *unicode_text));	if (unicode_text == NULL) {		printf("Out of memory\n");		return (NULL);	}	ASCII_to_UNICODE(unicode_text, text, unicode_len);	/* Render the new text */	textbuf = TTF_RenderUNICODE_Shaded(font, unicode_text, fg, bg);	/* Free the text buffer and return */	free(unicode_text);	return (textbuf);}void TTF_CloseFont(TTF_Font * font){	Flush_Cache(font);	FT_Done_Face(font->face);	free(font);}void TTF_SetFontStyle(TTF_Font * font, int style){	font->style = style;	Flush_Cache(font);}TTF_Font *TTF_OpenFontIndex(const char *file, int ptsize, long index){	TTF_Font *font;	FT_Error error;	FT_Face face;	FT_Fixed scale;	extern int strict_font;	font = (TTF_Font *) malloc(sizeof *font);	if (font == NULL) {		fprintf(stderr, "Out of memory\n");		return NULL;	}	memset(font, 0, sizeof(*font));	/* Open the font and create ancillary data */	error = FT_New_Face(library, file, 0, &font->face);	if (error && !strict_font)		error =		    FT_New_Memory_Face(library,				       (const FT_Byte *) luxisri_ttf,				       LUXISRI_SIZE, 0, &font->face);	if (error) {		printf("Couldn't load font file\n");		free(font);		return NULL;	}	if (index != 0) {		if (font->face->num_faces > index) {			FT_Done_Face(font->face);			error =			    FT_New_Face(library, file, index, &font->face);			if (error) {				printf("Couldn't get font face\n");				free(font);				return NULL;			}		} else {			fprintf(stderr, "No such font face\n");			free(font);			return NULL;		}	}	face = font->face;	/* Make sure that our font face is scalable (global metrics) */	if (!FT_IS_SCALABLE(face)) {		fprintf(stderr, "Font face is not scalable\n");		TTF_CloseFont(font);		return NULL;	}	/* Set the character size and use default DPI (72) */	error = FT_Set_Char_Size(font->face, 0, ptsize * 64, 0, 0);	if (error) {		fprintf(stderr, "Couldn't set font size\n");		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));	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;}TTF_Font *TTF_OpenFont(const char *file, int ptsize){	return TTF_OpenFontIndex(file, ptsize, 0);}static void Flush_Glyph(c_glyph * glyph){	glyph->stored = 0;	glyph->index = 0;	if (glyph->bitmap.buffer) {		free(glyph->bitmap.buffer);		glyph->bitmap.buffer = 0;	}	if (glyph->pixmap.buffer) {		free(glyph->pixmap.buffer);		glyph->pixmap.buffer = 0;	}	glyph->cached = 0;}static FT_Error Load_Glyph(TTF_Font * font, unsigned short ch,			   c_glyph * cached, int want){	FT_Face face;	FT_Error error;	FT_GlyphSlot glyph;	FT_Glyph_Metrics *metrics;	FT_Outline *outline;	assert(font);	assert(font->face);	face = font->face;	/* Load the glyph */	if (!cached->index) {		cached->index = FT_Get_Char_Index(face, ch);	}	error = FT_Load_Glyph(face, cached->index, FT_LOAD_DEFAULT);	if (error) {		return error;	}	/* Get our glyph shortcuts */	glyph = face->glyph;	metrics = &glyph->metrics;	outline = &glyph->outline;	/* Get the glyph metrics if desired */	if ((want & CACHED_METRICS) && !(cached->stored & CACHED_METRICS)) {		/* Get the bounding box */		cached->minx = FT_FLOOR(metrics->horiBearingX);		cached->maxx = cached->minx + FT_CEIL(metrics->width);		cached->maxy = FT_FLOOR(metrics->horiBearingY);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -