📄 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_HIGH
typedef 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_HIGH
typedef unsigned long OUTPIXELVAL;
#else
typedef 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_Error
xTT_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;
}
}
}
void
xTT_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_Error
xTT_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_Error
xTT_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_Error
xTT_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_Error
xTT_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_Error
xTT_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;
}
void
xTT_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_Error
xTT_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_Error
xTT_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
#endif
typedef 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;
#endif
typedef 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 256
typedef struct {
int width;
int height;
int size;
unsigned long use_count;
char * pFont;
char file[MAX_PATH + 1];
} HZKFONT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -