📄 devfont.caching.c
字号:
/* * Copyright (c) 2000 Greg Haerr <greg@censoft.com> * T1lib Adobe type1 routines contributed by Vidar Hokstad * Freetype TrueType routines contributed by Martin Jolicoeur * Han Zi Ku routines contributed by Tanghao and Jauming * * Device-independent font and text drawing routines * * These routines do the necessary range checking, clipping, and cursor * overwriting checks, and then call the lower level device dependent * routines to actually do the drawing. The lower level routines are * only called when it is known that all the pixels to be drawn are * within the device area and are visible. *//*#define NDEBUG*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <string.h>#include "device.h"#if (UNIX | DOS_DJGPP)#define strcmpi strcasecmp#endif#if HAVE_T1LIB_SUPPORT#include <t1lib.h>#define T1LIB_USE_AA_HIGHtypedef struct { PMWFONTPROCS fontprocs; /* common hdr*/ MWCOORD fontsize; int fontrotation; int fontattr; int fontid; /* t1lib stuff*/} MWT1LIBFONT, *PMWT1LIBFONT;static int t1lib_init(PSD psd);static PMWT1LIBFONT t1lib_createfont(const char *name, MWCOORD height,int attr);static void t1lib_drawtext(PMWFONT pfont, PSD psd, MWCOORD x, MWCOORD y, const void *text, int cc, int flags);static MWBOOL t1lib_getfontinfo(PMWFONT pfont, PMWFONTINFO pfontinfo);static void t1lib_gettextsize(PMWFONT pfont, const void *text, int cc, MWCOORD *pwidth, MWCOORD *pheight, MWCOORD *pbase);static void t1lib_destroyfont(PMWFONT pfont);/* handling routines for MWT1LIBFONT*/static MWFONTPROCS t1lib_procs = { MWTF_ASCII, /* routines expect ascii*/ t1lib_getfontinfo, t1lib_gettextsize, NULL, /* gettextbits*/ t1lib_destroyfont, t1lib_drawtext, NULL, /* setfontsize*/ NULL, /* setfontrotation*/ NULL, /* setfontattr*/};#endif#ifdef T1LIB_USE_AA_HIGHtypedef unsigned long OUTPIXELVAL;#elsetypedef MWPIXELVAL OUTPIXELVAL;#endif#if HAVE_FREETYPE_SUPPORT#include <freetype/freetype.h>#include <freetype/ftxkern.h>#include <freetype/ftnameid.h>#include <freetype/ftxcmap.h>#include <freetype/ftxwidth.h>#include <math.h>/************/typedef 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_ErrorxTT_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_ErrorxTT_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_ErrorxTT_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_ErrorxTT_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_ErrorxTT_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_ErrorxTT_Get_Glyph_Metrics ( xTT_Glyph glyph, TT_Glyph_Metrics * metrics ){ return TT_Get_Glyph_Metrics(*glyph.glyph->glyph,metrics);}TT_ErrorxTT_Get_Glyph_Outline ( xTT_Glyph glyph, xTT_Outline * outline ){ outline->outline = &glyph.glyph->outline; return 0;}TT_ErrorxTT_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);}#ifndef xTT_ALIAS#define xTT_ALIAS 1#endif#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/************/#ifndef FREETYPE_FONT_DIR#define FREETYPE_FONT_DIR "/usr/local/microwin/fonts"#endif#if TT_FREETYPE_MAJOR != 1 | TT_FREETYPE_MINOR < 3#error "You must link with freetype lib version 1.3.x +, and not freetype 2. \Download it at http://www.freetype.org or http://microwindows.org"#endif#ifndef MWFREETYPEFONT_CACHE#define MWFREETYPEFONT_CACHE 1#endif#if MWFREETYPEFONT_CACHE#ifndef MWFREETYPEFONT_CACHEBITMAP#define MWFREETYPEFONT_CACHEBITMAP 1#endiftypedef 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 { 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, *PMWFREETYPEFONT;static int freetype_init(PSD psd);static 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, 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, int 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*/};static TT_Engine engine; /* THE ONLY freetype engine */#endif /* HAVE_FREETYPE_SUPPORT*/#if HAVE_HZK_SUPPORT/* * 12x12 and 16x16 ascii and chinese fonts * Big5 and GB2312 encodings supported */#define MAX_PATH 256typedef struct { int width; int height; int size; unsigned long use_count; char * pFont; char file[MAX_PATH + 1];} HZKFONT;static int use_big5=1;static HZKFONT CFont[2]; /* font cache*/static HZKFONT AFont[2]; /* font cache*//*jmt: moved inside MWHZKFONT*/static int afont_width = 8;static int cfont_width = 16;static int font_height = 16;static char *afont_address;static char *cfont_address;typedef struct { PMWFONTPROCS fontprocs; /* common hdr*/ MWCOORD fontsize; int fontrotation; int fontattr; HZKFONT CFont; /* hzkfont stuff */ HZKFONT AFont; int afont_width; int cfont_width; int font_height; char *afont_address; char *cfont_address;} MWHZKFONT, *PMWHZKFONT;static int hzk_init(PSD psd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -