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 + -
显示快捷键?