📄 font_freetype.cache.c
字号:
/* * Copyright (c) 2000, 2002 Greg Haerr <greg@censoft.com> * Portions Copyright (c) 2002 by Koninklijke Philips Electronics N.V. * * Caching freetype routines - permanently broken * Written by Scott D. Robinson *//*#define NDEBUG*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <freetype/freetype.h>#include <freetype/ftxkern.h>#include <freetype/ftnameid.h>#include <freetype/ftxcmap.h>#include <freetype/ftxwidth.h>#include <math.h>#include <dirent.h>#include "device.h"#include "devfont.h"#define MWFREETYPEFONT_CACHE 1#define MWFREETYPEFONT_CACHEBITMAP 1#define xTT_ALIAS 1#if TT_FREETYPE_MAJOR != 1 | TT_FREETYPE_MINOR < 3#error "You must link with freetype lib version 1.3.x +, and not freetype 2."#endiftypedef struct xTT_Glyph_Cache_ { TT_Error error; TT_Glyph glyph; TT_UShort index; TT_UShort flags; struct xTT_Glyph_Cache_ *l; struct xTT_Glyph_Cache_ *r;} xTT_Glyph_Cache;typedef struct xTT_Instance_Object_ { TT_Face face; TT_Instance instance; xTT_Glyph_Cache *head;} xTT_Instance_Object;typedef struct xTT_Instance_ { xTT_Instance_Object *instance;} xTT_Instance;typedef struct xTT_Outline_Object_ { TT_Outline outline; TT_BBox bbox;} xTT_Outline_Object;typedef struct xTT_Outline_ { xTT_Outline_Object *outline;} xTT_Outline;typedef struct xTT_Glyph_Object_ { TT_Glyph *glyph; xTT_Outline_Object outline;} xTT_Glyph_Object;typedef struct xTT_Glyph_ { xTT_Glyph_Object *glyph;} xTT_Glyph;TT_ErrorxTT_Glyph_Cache_Find(xTT_Instance instance, xTT_Glyph glyph, TT_UShort glyphIndex, TT_UShort loadFlags){ xTT_Glyph_Cache *node; xTT_Glyph_Cache **inode = &instance.instance->head; int miss = 0; while (1) { if (*inode == 0) { miss = 1; node = *inode = calloc(1, sizeof(**inode)); if (node == 0) return TT_Err_Out_Of_Memory; node->error = TT_New_Glyph(instance.instance->face, &(node->glyph)); if (node->error == 0) node->error = TT_Load_Glyph(instance.instance-> instance, node->glyph, (node->index = glyphIndex), (node->flags = loadFlags)); if (node->error != 0) TT_Done_Glyph(node->glyph); } else { node = *inode; } if (glyphIndex < node->index) inode = &node->l; else if (glyphIndex > node->index) inode = &node->r; else if (loadFlags < node->flags) inode = &node->l; else if (loadFlags > node->flags) inode = &node->r; else { static int count[] = { 0, 0 }; ++count[miss]; printf("\r(%s | hit %d | miss %d)", __TIME__, count[0], count[1]); glyph.glyph->glyph = &node->glyph; return node->error; } }}voidxTT_Glyph_Cache_Free(xTT_Glyph_Cache ** pnode){ xTT_Glyph_Cache *node; if (pnode == 0) return; node = *pnode; if (node == 0) return; if (node->l) xTT_Glyph_Cache_Free(&node->l); if (node->r) xTT_Glyph_Cache_Free(&node->r); TT_Done_Glyph(node->glyph); free(node); *pnode = 0;}TT_Error xTT_New_Instance(TT_Face face, xTT_Instance * instance){ instance->instance = calloc(1, sizeof(*instance->instance)); if (instance->instance == 0) return TT_Err_Out_Of_Memory; instance->instance->face = face; instance->instance->head = 0; return TT_New_Instance(face, &instance->instance->instance);}TT_Error xTT_Done_Instance(xTT_Instance instance){ TT_Error error; xTT_Glyph_Cache_Free(&instance.instance->head); error = TT_Done_Instance(instance.instance->instance); free(instance.instance); return error;}TT_ErrorxTT_Get_Instance_Metrics(xTT_Instance instance, TT_Instance_Metrics * imetrics){ return TT_Get_Instance_Metrics(instance.instance->instance, imetrics);}TT_Error xTT_Set_Instance_CharSize(xTT_Instance instance, TT_F26Dot6 charsize){ xTT_Glyph_Cache_Free(&instance.instance->head); return TT_Set_Instance_CharSize(instance.instance->instance, charsize);}TT_ErrorxTT_Set_Instance_PixelSizes(xTT_Instance instance, TT_UShort pixelWidth, TT_UShort pixelHeight, TT_F26Dot6 pointSize){ xTT_Glyph_Cache_Free(&instance.instance->head); return TT_Set_Instance_PixelSizes(instance.instance->instance, pixelWidth, pixelHeight, pointSize);}TT_ErrorxTT_Set_Instance_Transform_Flags(xTT_Instance instance, TT_Bool rotated, TT_Bool stretched){ xTT_Glyph_Cache_Free(&instance.instance->head); return TT_Set_Instance_Resolutions(instance.instance->instance, rotated, stretched);}TT_ErrorxTT_Set_Instance_Resolutions(xTT_Instance instance, TT_UShort xResolution, TT_UShort yResolution){ xTT_Glyph_Cache_Free(&instance.instance->head); return TT_Set_Instance_Resolutions(instance.instance->instance, xResolution, yResolution);}TT_Error xTT_New_Glyph(TT_Face face, xTT_Glyph * glyph){ glyph->glyph = calloc(1, sizeof(*glyph->glyph)); if (glyph->glyph == 0) return TT_Err_Out_Of_Memory; return 0;}TT_Error xTT_Done_Glyph(xTT_Glyph glyph){ free(glyph.glyph); return 0;}TT_ErrorxTT_Load_Glyph(xTT_Instance instance, xTT_Glyph glyph, TT_UShort glyphIndex, TT_UShort loadFlags){ TT_Error error; error = xTT_Glyph_Cache_Find(instance, glyph, glyphIndex, loadFlags); TT_Get_Glyph_Outline(*glyph.glyph->glyph, &glyph.glyph->outline.outline); TT_Get_Outline_BBox(&glyph.glyph->outline.outline, &glyph.glyph->outline.bbox); return error;}TT_Error xTT_Get_Glyph_Metrics(xTT_Glyph glyph, TT_Glyph_Metrics * metrics){ return TT_Get_Glyph_Metrics(*glyph.glyph->glyph, metrics);}TT_Error xTT_Get_Glyph_Outline(xTT_Glyph glyph, xTT_Outline * outline){ outline->outline = &glyph.glyph->outline; return 0;}TT_Error xTT_Get_Outline_BBox(xTT_Outline * outline, TT_BBox * bbox){ *bbox = outline->outline->bbox; return 0;}voidxTT_Transform_Outline(xTT_Outline * outline, TT_Matrix * matrix){ TT_Transform_Outline(&outline->outline->outline, matrix); TT_Get_Outline_BBox(&outline->outline->outline, &outline->outline->bbox);}TT_ErrorxTT_Get_Glyph_Bitmap(xTT_Glyph glyph, TT_Raster_Map * bitmap, TT_F26Dot6 xOffset, TT_F26Dot6 yOffset){ return TT_Get_Glyph_Bitmap(*glyph.glyph->glyph, bitmap, xOffset, yOffset);}TT_ErrorxTT_Get_Glyph_Pixmap(xTT_Glyph glyph, TT_Raster_Map * pixmap, TT_F26Dot6 xOffset, TT_F26Dot6 yOffset){ return TT_Get_Glyph_Pixmap(*glyph.glyph->glyph, pixmap, xOffset, yOffset);}#if xTT_ALIAS#define TT_Instance xTT_Instance#define TT_Outline xTT_Outline#define TT_Glyph xTT_Glyph#define TT_New_Instance xTT_New_Instance#define TT_Done_Instance xTT_Done_Instance#define TT_Get_Instance_Metrics xTT_Get_Instance_Metrics#define TT_Set_Instance_CharSize xTT_Set_Instance_CharSize#define TT_Set_Instance_PixelSizes xTT_Set_Instance_PixelSizes#define TT_Set_Instance_Transform_Flags xTT_Set_Instance_Transform_Flags#define TT_Set_Instance_Resolutions xTT_Set_Instance_Resolutions#define TT_New_Glyph xTT_New_Glyph#define TT_Done_Glyph xTT_Done_Glyph#define TT_Load_Glyph xTT_Load_Glyph#define TT_Get_Glyph_Metrics xTT_Get_Glyph_Metrics#define TT_Get_Glyph_Outline xTT_Get_Glyph_Outline#define TT_Get_Glyph_Bitmap xTT_Get_Glyph_Bitmap#define TT_Get_Glyph_Pixmap xTT_Get_Glyph_Pixmap#define TT_Get_Outline_BBox xTT_Get_Outline_BBox#define TT_Transform_Outline xTT_Transform_Outline#endif#if MWFREETYPEFONT_CACHEtypedef struct mwfreetypefontcache { unsigned curchar; void *buffer;#if MWFREETYPEFONT_CACHEBITMAP MWPIXELVAL fg; MWPIXELVAL bg; MWBOOL usebg; void *bitmap;#endif struct mwfreetypefontcache *l; struct mwfreetypefontcache *r;} MWFREETYPEFONTCACHE;#endiftypedef struct MWFREETYPEFONT { PMWFONTPROCS fontprocs; /* common hdr*/ MWCOORD fontsize; int fontrotation; int fontattr; TT_Face face; /* freetype stuff*/ TT_Instance instance; TT_CharMap char_map; TT_Kerning directory; TT_Matrix matrix; TT_Glyph glyph; MWBOOL can_kern; short last_glyph_code; short last_pen_pos;#if MWFREETYPEFONT_CACHE MWFREETYPEFONTCACHE * glyph_cache;#endif} MWFREETYPEFONT;int freetype_init(PSD psd);PMWFREETYPEFONT freetype_createfont(const char *name, MWCOORD height, int attr);static MWBOOL freetype_getfontinfo(PMWFONT pfont, PMWFONTINFO pfontinfo);static void freetype_gettextsize(PMWFONT pfont, const void *text, int cc, MWTEXTFLAGS flags, MWCOORD *pwidth, MWCOORD *pheight, MWCOORD *pbase);static void freetype_destroyfont(PMWFONT pfont);static void freetype_drawtext(PMWFONT pfont, PSD psd, MWCOORD x, MWCOORD y, const void *text, int cc, MWTEXTFLAGS flags);static void freetype_setfontsize(PMWFONT pfont, MWCOORD fontsize);static void freetype_setfontrotation(PMWFONT pfont, int tenthdegrees); /* handling routines for MWFREETYPEFONT*/static MWFONTPROCS freetype_procs = { MWTF_UC16, /* routines expect unicode 16*/ freetype_getfontinfo, freetype_gettextsize, NULL, /* gettextbits*/ freetype_destroyfont, freetype_drawtext, freetype_setfontsize, freetype_setfontrotation, NULL, /* setfontattr*/ NULL, /* duplicate not yet implemented */};static TT_Engine engine; /* THE ONLY freetype engine */static OUTPIXELVAL gray_palette[5];/* temp extern decls*/extern MWPIXELVAL gr_foreground;extern MWPIXELVAL gr_background;extern MWBOOL gr_usebg;intfreetype_init(PSD psd){ static int inited = 0; if (inited) return 1; /* Init freetype library */ if (TT_Init_FreeType (&engine) != TT_Err_Ok) { return 0; } /* Init kerning extension */ if (TT_Init_Kerning_Extension (engine) != TT_Err_Ok) return 0; inited = 1; return 1;}PMWFREETYPEFONTfreetype_createfont(const char *name, MWCOORD height, int attr){ PMWFREETYPEFONT pf; unsigned short i, n; unsigned short platform, encoding; TT_Face_Properties properties; char * p; char fontname[128]; /* check for pathname prefix*/ if (strchr(name, '/') != NULL) strcpy(fontname, name); else { strcpy(fontname, FREETYPE_FONT_DIR); strcat(fontname, "/"); strcat(fontname, name); } /* check for extension*/ if ((p = strrchr(fontname, '.')) == NULL || strcmp(p, ".ttf") != 0) { strcat(fontname, ".ttf"); } /* allocate font structure*/ pf = (PMWFREETYPEFONT)calloc(sizeof(MWFREETYPEFONT), 1); if (!pf) return NULL; pf->fontprocs = &freetype_procs; /* Load face */ if (TT_Open_Face (engine, fontname, &pf->face) != TT_Err_Ok) goto out; /* Load first kerning table */ pf->can_kern = TRUE; if (TT_Load_Kerning_Table (pf->face, 0) != TT_Err_Ok) pf->can_kern = FALSE; else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -