📄 gfxfont.c
字号:
/*----------------------------------------------------------------------------+| This source code has been made available to you by IBM on an AS-IS| basis. Anyone receiving this source is licensed under IBM| copyrights to use it in any way he or she deems fit, including| copying it, modifying it, compiling it, and redistributing it either| with or without modifications. No license under IBM patents or| patent applications is to be implied by the copyright license.|| Any user of this software should understand that IBM cannot provide| technical support for this software and will not be responsible for| any consequences resulting from the use of this software.|| Any person who transfers this source code or any derivative work| must include the IBM copyright notice, this paragraph, and the| preceding two paragraphs in the transferred software.|| IBM CONFIDENTIAL| (C) COPYRIGHT IBM CORPORATION 1999, 2001 +-----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| Author: Yudong Yang| Component: | File: gfxfont.c| Purpose: Font rendering interface functions (using freetype2 library).| Changes:| Date: Author Comment:| ----- ------ --------| 08-Apr-02 YYD Created+----------------------------------------------------------------------------*/#include <stdlib.h>#include <string.h>#include <stdio.h>//#include <freetype.h>#include <ft2build.h>#include FT_FREETYPE_H#include FT_GLYPH_H#include "gfxlib.h"int gfx_load_font_freetype2( int fdGfxDev, GFX_FONT_INFO_T *pFont, GFX_FONT_ENCODING_T encoding, unsigned int charStart, unsigned int charEnd, unsigned int uWidth, unsigned int uHeight, char * pFontPath ){ FT_Library ft_library; FT_Face face; int rtn; if(!pFont || charStart > charEnd || !uWidth || !uHeight) { fprintf(stderr, "Invalid parameters !\n"); return -1; } memset(pFont, 0, sizeof(GFX_FONT_INFO_T)); if(!pFontPath) pFontPath = "/usr/share/fonts/helv.ttf"; rtn = FT_Init_FreeType(&ft_library); if(rtn) { fprintf(stderr, "Failed to init FreeType2 library!\n"); return -1; } rtn = FT_New_Face(ft_library, pFontPath, 0, &face); if(rtn) { fprintf(stderr, "Failed to load font '%s', rtn= %d !\n", pFontPath, rtn); goto clean_up1; } //if(face->flags & FT_FACE_FLAG_SCALABLE) // is scalable font //{ rtn = FT_Set_Pixel_Sizes( face, uWidth, uHeight); if(rtn) { fprintf(stderr, "Failed to set font size to %dx%d, rtn= %d !\n", pFontPath, rtn); goto clean_up; } //} //else // look for a near size //{ // int i; // for(i=0; i< //}#if 0 // look for available charmap { FT_CharMap found = 0; FT_CharMap charmap; int n; switch(encoding) { case GFX_FONT_ASCII: charmap = ft_encoding_latin_2; break; case GFX_FONT_GB2312: charmap = ft_encoding_gb2312; break; case GFX_FONT_UNICODE: charmap = ft_encoding_unicode; break; } for ( n = 0; n < face->num_charmaps; n++ ) { if (face->charmaps[n]->encoding == charmap) { found = charmap; break; } } if(!found) { fprintf(stderr, "Failed to find font encoding %d !\n", encoding); rtn = -1; goto clean_up; } FT_Set_Charmap( face, found ); }#endif // try to get included glyphs { int i,j, c; int xp, yp, xmax, ymax, t; FT_Glyph glyph; FT_BitmapGlyph glyph_bitmap; int *xadv, *yadv; int *cmap; pFont->uWidth = malloc(sizeof(unsigned int)*(charEnd - charStart+1)*3); if(!pFont->uWidth) { fprintf(stderr, "Failed to allocate buffer!\n"); free(cmap); rtn = -1; goto clean_up; } pFont->uPosX = pFont->uWidth + charEnd - charStart+1; pFont->uPosY = pFont->uPosX + charEnd - charStart+1; cmap = malloc(face->num_glyphs * 2 * sizeof(int) + (charEnd - charStart+1) * sizeof(int)); if(!cmap) { fprintf(stderr, "Failed to alloc working buffer!\n"); free(pFont->uWidth); rtn = -1; goto clean_up; } xadv = cmap + charEnd - charStart+1; yadv = xadv + face->num_glyphs; memset(cmap, 0xff, (charEnd - charStart+1) * sizeof(int)); memset(xadv, 0, face->num_glyphs * 2 * sizeof(int)); xmax = ymax = 0; for(c=charStart; c<=charEnd; c++) { int glyph_index = FT_Get_Char_Index(face, c); FT_GlyphSlot slot; rtn = FT_Load_Glyph( face, /* handle to face object */ glyph_index, /* glyph index */ FT_LOAD_DEFAULT ); /* load flags, see below */ if(rtn) continue; cmap[c-charStart] = glyph_index;#if 1 // extract glyph image rtn = FT_Get_Glyph( face->glyph, &glyph ); // convert to a bitmap (default render mode + destroy old) if ( glyph->format != ft_glyph_format_bitmap ) { rtn = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 ); if ( rtn ) continue; // glyph unchanged } glyph_bitmap = (FT_BitmapGlyph)glyph; xadv[glyph_index] = face->glyph->advance.x >> 6; if(glyph_bitmap->left < 0) { if(xadv[glyph_index] < glyph_bitmap->bitmap.width-glyph_bitmap->left) // some glyphs has adv = 0; xadv[glyph_index] = glyph_bitmap->bitmap.width-glyph_bitmap->left; } else { if(xadv[glyph_index] < glyph_bitmap->bitmap.width+glyph_bitmap->left) // some glyphs has adv = 0; xadv[glyph_index] = glyph_bitmap->bitmap.width+glyph_bitmap->left; }// yadv[glyph_index] = face->glyph->advance.y >> 6; yadv[glyph_index] = (face->glyph->linearVertAdvance + 0xffff)>>16; //slot->metrics.vertAdvance>>6; // discard glyph image (bitmap or not) FT_Done_Glyph( glyph ); #else slot = face->glyph; cmap[c-charStart] = glyph_index; xadv[glyph_index] = (slot->linearHoriAdvance + 0xffff)>>16; // slot->metrics.horiAdvance>>6; yadv[glyph_index] = (slot->linearVertAdvance + 0xffff)>>16; //slot->metrics.vertAdvance>>6;#endif pFont->uWidth[c-charStart] = xadv[glyph_index]; //printf("char %d (%c), glyph %3d : xadv = %d yadv = %d\n", c, c, glyph_index, // xadv[glyph_index], yadv[glyph_index]); if(xadv[glyph_index] > xmax ) xmax = xadv[glyph_index]; if(yadv[glyph_index] > ymax ) ymax = yadv[glyph_index]; } //printf("xmax = %d, ymax = %d\n", xmax, ymax); // now calculate the layout of bitmapped glyphs pFont->uMaxWidth = xmax; pFont->uHeight = ymax; pFont->uMaxChar = charEnd; pFont->uMinChar = charStart; xmax = 0; ymax = 0; xp = yp = 0; for(i=0; i<face->num_glyphs; i++) { if(xadv[i] == 0 && yadv[i] == 0) continue; // unused slots if(xadv[i] + xp >= GFX_SURFACE_MAX_WIDTH) // next row { // printf("next line\n"); xp = 0; yp += pFont->uHeight; } t = xadv[i]; xadv[i] = xp; yadv[i] = yp; xp += (t&1) ? t+1 : t ; // compensate for the even pixel alignment of YUV422 planes if(xp > xmax) xmax = xp; } ymax = yp + pFont->uHeight; // now xmax * ymax is the required bitmap for(c=charStart; c<=charEnd; c++) { pFont->uPosX[c-charStart] = xadv[cmap[c-charStart]]; pFont->uPosY[c-charStart] = yadv[cmap[c-charStart]]; // printf("%3d : posx, posy = %4d, %4d\n", c, pFont->uPosX[c-charStart], pFont->uPosY[c-charStart]); } // create surface as xmax * ymax // printf("xdim = %d, ydim = %d \n", xmax, ymax); pFont->hFont = gfx_create_surface(fdGfxDev, xmax, ymax, GFX_SURFACE_RAW8BPP, GFX_VDEV_NULL, 0); if(pFont->hFont < 0) { fprintf(stderr, "Failed to create 8 bit font surface !\n"); free(cmap); free(pFont->uWidth); rtn = -1; goto clean_up; } pFont->hMonoFont = gfx_create_surface(fdGfxDev, xmax, ymax, GFX_SURFACE_RAW1BPP, GFX_VDEV_NULL, 0); if(pFont->hMonoFont < 0) { fprintf(stderr, "Failed to create 1 bit font surface!\n"); free(cmap); free(pFont->uWidth); rtn = -1; goto clean_up; } pFont->hScratch = gfx_create_surface(fdGfxDev, pFont->uMaxWidth*2, pFont->uHeight, GFX_SURFACE_ARGB_8888, GFX_VDEV_NULL, 0xffffffff); if(pFont->hScratch < 0) { fprintf(stderr, "Failed to create font scratch surface !\n"); gfx_destroy_surface(fdGfxDev, pFont->hMonoFont); gfx_destroy_surface(fdGfxDev, pFont->hFont); free(cmap); free(pFont->uWidth);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -