font_load_ft.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,172 行 · 第 1/3 页

C
1,172
字号
/* * Renders antialiased fonts for mplayer using freetype library. * Should work with TrueType, Type1 and any other font supported by libfreetype. * * Artur Zaprzala <zybi@fanthom.irc.pl> * * ported inside mplayer by Jindrich Makovicka  * <makovick@gmail.com> * */#include "config.h"#include <mplaylib.h>#include <mplaylib.h>#include <math.h>#include <mplaylib.h>#ifdef USE_ICONV#include <iconv.h>#endif#include <ft2build.h>#include FT_FREETYPE_H#include FT_GLYPH_H#ifdef HAVE_FONTCONFIG#include <fontconfig/fontconfig.h>#endif#include "libavutil/common.h"#include "mpbswap.h"#include "font_load.h"#include "mp_msg.h"#include "mplayer.h"#include "get_path.h"#include "osd_font.h"#undef memcpy#define memcpy uc_memcpy#if (FREETYPE_MAJOR > 2) || (FREETYPE_MAJOR == 2 && FREETYPE_MINOR >= 1)#define HAVE_FREETYPE21#endifchar *subtitle_font_encoding = NULL;float text_font_scale_factor = 5.0;float osd_font_scale_factor = 6.0;float subtitle_font_radius = 2.0;float subtitle_font_thickness = 2.0;// 0 = no autoscale// 1 = video height// 2 = video width// 3 = diagonalint subtitle_autoscale = 3;int vo_image_width = 0;int vo_image_height = 0;int force_load_font;int using_freetype = 0;int font_fontconfig = 0;//// constantsstatic unsigned int const colors = 256;static unsigned int const maxcolor = 255;static unsigned const	base = 256;static unsigned const first_char = 33;#define MAX_CHARSET_SIZE 60000static FT_Library library;#define OSD_CHARSET_SIZE 15static FT_ULong	osd_charset[OSD_CHARSET_SIZE] ={    0xe001, 0xe002, 0xe003, 0xe004, 0xe005, 0xe006, 0xe007, 0xe008,    0xe009, 0xe00a, 0xe00b, 0xe010, 0xe011, 0xe012, 0xe013};static FT_ULong	osd_charcodes[OSD_CHARSET_SIZE] ={    0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,    0x09,0x0a,0x0b,0x10,0x11,0x12,0x13};#define f266ToInt(x)		(((x)+32)>>6)	// round fractional fixed point number to integer						// coordinates are in 26.6 pixels (i.e. 1/64th of pixels)#define f266CeilToInt(x)	(((x)+63)>>6)	// ceiling#define f266FloorToInt(x)	((x)>>6)	// floor#define f1616ToInt(x)		(((x)+0x8000)>>16)	// 16.16#define floatTof266(x)		((int)((x)*(1<<6)+0.5))#define ALIGN(x)                (((x)+7)&~7)    // 8 byte align#define WARNING(msg, args...)      mp_msg(MSGT_OSD, MSGL_WARN, msg "\n", ## args)#define DEBUG 0//static double ttime;static void paste_bitmap(unsigned char *bbuffer, FT_Bitmap *bitmap, int x, int y, int width, int height, int bwidth) {    int drow = x+y*width;    int srow = 0;    int sp, dp, w, h;    if (bitmap->pixel_mode==ft_pixel_mode_mono)	for (h = bitmap->rows; h>0 && height > 0; --h, height--, drow+=width, srow+=bitmap->pitch)	    for (w = bwidth, sp=dp=0; w>0; --w, ++dp, ++sp)		    bbuffer[drow+dp] = (bitmap->buffer[srow+sp/8] & (0x80>>(sp%8))) ? 255:0;    else	for (h = bitmap->rows; h>0 && height > 0; --h, height--, drow+=width, srow+=bitmap->pitch)	    for (w = bwidth, sp=dp=0; w>0; --w, ++dp, ++sp)		    bbuffer[drow+dp] = bitmap->buffer[srow+sp];}static int check_font(font_desc_t *desc, float ppem, int padding, int pic_idx,		      int charset_size, FT_ULong *charset, FT_ULong *charcodes,		      int unicode) {    FT_Error	error;    FT_Face face = desc->faces[pic_idx];    int	const	load_flags = FT_LOAD_DEFAULT;    int		ymin = INT_MAX, ymax = INT_MIN;    int		space_advance = 20;    int         width, height;    unsigned char *bbuffer;    int i, uni_charmap = 1;        error = FT_Select_Charmap(face, ft_encoding_unicode);//    fprintf(stderr, "select unicode charmap: %d\n", error);    if (face->charmap==NULL || face->charmap->encoding!=ft_encoding_unicode) {	WARNING("Unicode charmap not available for this font. Very bad!");	uni_charmap = 0;	error = FT_Set_Charmap(face, face->charmaps[0]);	if (error) WARNING("No charmaps! Strange.");    }    /* set size */    if (FT_IS_SCALABLE(face)) {	error = FT_Set_Char_Size(face, 0, floatTof266(ppem), 0, 0);	if (error) WARNING("FT_Set_Char_Size failed.");    } else {	int j = 0;	int jppem = face->available_sizes[0].height;	/* find closest size */	for (i = 0; i<face->num_fixed_sizes; ++i) {	    if (fabs(face->available_sizes[i].height - ppem) < abs(face->available_sizes[i].height - jppem)) {		j = i;		jppem = face->available_sizes[i].height;	    }	}	WARNING("Selected font is not scalable. Using ppem=%i.", face->available_sizes[j].height);	error = FT_Set_Pixel_Sizes(face, face->available_sizes[j].width, face->available_sizes[j].height);	if (error) WARNING("FT_Set_Pixel_Sizes failed.");    }    if (FT_IS_FIXED_WIDTH(face))	WARNING("Selected font is fixed-width.");    /* compute space advance */    error = FT_Load_Char(face, ' ', load_flags);    if (error) WARNING("spacewidth set to default.");    else space_advance = f266ToInt(face->glyph->advance.x);    if (!desc->spacewidth) desc->spacewidth = 2*padding + space_advance;    if (!desc->charspace) desc->charspace = -2*padding;    if (!desc->height) desc->height = f266ToInt(face->size->metrics.height);    for (i= 0; i<charset_size; ++i) {	FT_ULong	character, code;	FT_UInt		glyph_index;	character = charset[i];	code = charcodes[i];	desc->font[unicode?character:code] = pic_idx;	// get glyph index	if (character==0)	    glyph_index = 0;	else {	    glyph_index = FT_Get_Char_Index(face, uni_charmap ? character:code);	    if (glyph_index==0) {		WARNING("Glyph for char 0x%02lx|U+%04lX|%c not found.", code, character,			code<' '||code>255 ? '.':(char)code);		desc->font[unicode?character:code] = -1;		continue;	    }	}	desc->glyph_index[unicode?character:code] = glyph_index;    }//    fprintf(stderr, "font height: %lf\n", (double)(face->bbox.yMax-face->bbox.yMin)/(double)face->units_per_EM*ppem);//    fprintf(stderr, "font width: %lf\n", (double)(face->bbox.xMax-face->bbox.xMin)/(double)face->units_per_EM*ppem);    ymax = (double)(face->bbox.yMax)/(double)face->units_per_EM*ppem+1;    ymin = (double)(face->bbox.yMin)/(double)face->units_per_EM*ppem-1;        width = ppem*(face->bbox.xMax-face->bbox.xMin)/face->units_per_EM+3+2*padding;    if (desc->max_width < width) desc->max_width = width;    width = ALIGN(width);    desc->pic_b[pic_idx]->charwidth = width;    if (width <= 0) {	mp_msg(MSGT_OSD, MSGL_ERR, "Wrong bounding box, width <= 0 !\n");	return -1;    }    if (ymax<=ymin) {	mp_msg(MSGT_OSD, MSGL_ERR, "Something went wrong. Use the source!\n");	return -1;    }        height = ymax - ymin + 2*padding;    if (height <= 0) {	mp_msg(MSGT_OSD, MSGL_ERR, "Wrong bounding box, height <= 0 !\n");	return -1;    }    if (desc->max_height < height) desc->max_height = height;    desc->pic_b[pic_idx]->charheight = height;    //    fprintf(stderr, "font height2: %d\n", height);    desc->pic_b[pic_idx]->baseline = ymax + padding;    desc->pic_b[pic_idx]->padding = padding;    desc->pic_b[pic_idx]->current_alloc = 0;    desc->pic_b[pic_idx]->current_count = 0;    bbuffer = NULL;        desc->pic_b[pic_idx]->w = width;    desc->pic_b[pic_idx]->h = height;    desc->pic_b[pic_idx]->c = colors;    desc->pic_b[pic_idx]->bmp = bbuffer;    desc->pic_b[pic_idx]->pen = 0;    return 0;}// general outlinestatic void outline(	unsigned char *s,	unsigned char *t,	int width,	int height,	int stride,	unsigned char *m,	int r,	int mwidth,	int msize) {    int x, y;        for (y = 0; y<height; y++) {	for (x = 0; x<width; x++) {	    const int src= s[x];	    if(src==0) continue;	    {		const int x1=(x<r) ? r-x : 0;		const int y1=(y<r) ? r-y : 0;		const int x2=(x+r>=width ) ? r+width -x : 2*r+1;		const int y2=(y+r>=height) ? r+height-y : 2*r+1;		register unsigned char *dstp= t + (y1+y-r)* stride + x-r;		//register int *mp  = m +  y1     *mwidth;		register unsigned char *mp= m + msize*src + y1*mwidth;		int my;		for(my= y1; my<y2; my++){		    register int mx;		    for(mx= x1; mx<x2; mx++){			if(dstp[mx] < mp[mx]) dstp[mx]= mp[mx];		    }		    dstp+=stride;		    mp+=mwidth;		}            }	}	s+= stride;    }}// 1 pixel outlinestatic void outline1(	unsigned char *s,	unsigned char *t,	int width,	int height,	int stride) {    int x, y;    int skip = stride-width;    for (x = 0; x<width; ++x, ++s, ++t) *t = *s;    s += skip;    t += skip;    for (y = 1; y<height-1; ++y) {	*t++ = *s++;	for (x = 1; x<width-1; ++x, ++s, ++t) {	    unsigned v = (		    s[-1-stride]+		    s[-1+stride]+		    s[+1-stride]+		    s[+1+stride]		)/2 + (		    s[-1]+		    s[+1]+		    s[-stride]+		    s[+stride]+		    s[0]		);	    *t = v>maxcolor ? maxcolor : v;	}	*t++ = *s++;	s += skip;	t += skip;    }    for (x = 0; x<width; ++x, ++s, ++t) *t = *s;}// "0 pixel outline"static void outline0(	unsigned char *s,	unsigned char *t,	int width,	int height,	int stride) {    int y;    for (y = 0; y<height; ++y) {	memcpy(t, s, width);	s += stride;	t += stride;    }}// gaussian blurvoid blur(	unsigned char *buffer,	unsigned short *tmp2,	int width,	int height,	int stride,	int *m2,	int r,	int mwidth) {    int x, y;    unsigned char  *s = buffer;    unsigned short *t = tmp2+1;    for(y=0; y<height; y++){	memset(t-1, 0, (width+1)*sizeof(short));	for(x=0; x<r; x++){	    const int src= s[x];	    if(src){		register unsigned short *dstp= t + x-r;		int mx;		unsigned *m3= m2 + src*mwidth;		for(mx=r-x; mx<mwidth; mx++){		    dstp[mx]+= m3[mx];		}	    }	}	for(; x<width-r; x++){	    const int src= s[x];	    if(src){		register unsigned short *dstp= t + x-r;		int mx;		unsigned *m3= m2 + src*mwidth;		for(mx=0; mx<mwidth; mx++){		    dstp[mx]+= m3[mx];		}	    }	}	for(; x<width; x++){	    const int src= s[x];	    if(src){		register unsigned short *dstp= t + x-r;		int mx;		const int x2= r+width -x;		unsigned *m3= m2 + src*mwidth;		for(mx=0; mx<x2; mx++){		    dstp[mx]+= m3[mx];		}	    }	}	s+= stride;	t+= width + 1;    }

⌨️ 快捷键说明

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