⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devfont.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * 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>

#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

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;
} 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;

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);
static PMWHZKFONT hzk_createfont(const char *name, MWCOORD height,int fontattr);
static MWBOOL hzk_getfontinfo(PMWFONT pfont, PMWFONTINFO pfontinfo);
static void hzk_gettextsize(PMWFONT pfont, const void *text,
		int cc, MWCOORD *pwidth, MWCOORD *pheight, MWCOORD *pbase);
#if 0
static void hzk_gettextbits(PMWFONT pfont, int ch, IMAGEBITS *retmap,
		MWCOORD *pwidth, MWCOORD *pheight, MWCOORD *pbase);
static void hzk_setfontrotation(PMWFONT pfont, int tenthdegrees);
#endif
static void hzk_destroyfont(PMWFONT pfont);
static void hzk_drawtext(PMWFONT pfont, PSD psd, MWCOORD x, MWCOORD y,
		const void *text, int cc, int flags);
static void hzk_setfontsize(PMWFONT pfont, MWCOORD fontsize);
		
/* handling routines for MWHZKFONT*/
static MWFONTPROCS hzk_procs = {
	MWTF_ASCII,			/* routines expect ASCII*/
	hzk_getfontinfo,
	hzk_gettextsize,
	NULL,				/* hzk_gettextbits*/
	hzk_destroyfont,
	hzk_drawtext,
	hzk_setfontsize,
	NULL, 				/* setfontrotation*/
	NULL,				/* setfontattr*/
};

static int
UC16_to_GB(const unsigned char *uc16, int cc, unsigned char *ascii);
#endif /* HAVE_HZK_SUPPORT*/

static PMWFONT	gr_pfont;            	/* current font*/

/* temp extern decls*/
extern MWPIXELVAL gr_foreground;
extern MWPIXELVAL gr_background;
extern MWBOOL gr_usebg;

static int  utf8_to_utf16(const unsigned char *utf8, int cc,
		unsigned short *unicode16);

#if FONTMAPPER
/* entry point for font selection*/
int select_font(const PMWLOGFONT plogfont, char *physname);
#endif

/*
 * Set the font for future calls.
 */
PMWFONT
GdSetFont(PMWFONT pfont)
{
	PMWFONT	oldfont = gr_pfont;

	gr_pfont = pfont;
	return oldfont;
}

/*
 * Select a font, based on various parameters.
 * If plogfont is specified, name and height parms are ignored
 * and instead used from MWLOGFONT.
 * 
 * If height is 0, return builtin font from passed name.
 * Otherwise find builtin font best match based on height.
 */
PMWFONT
GdCreateFont(PSD psd, const char *name, MWCOORD height,
	const PMWLOGFONT plogfont)
{
	int 		i;
	int		fontht;
	int		fontno;
 	int		fontclass;
	int		fontattr = 0;
	PMWFONT		pfont;
	PMWCOREFONT	pf = psd->builtin_fonts;
	MWFONTINFO	fontinfo;
	MWSCREENINFO 	scrinfo;
 	char		fontname[128];

	GdGetScreenInfo(psd, &scrinfo);

	/* if plogfont not specified, use name and height*/
	if (!plogfont) {
		if (!name)
			name = MWFONT_SYSTEM_VAR;
		strcpy(fontname, name);
		fontclass = MWLF_CLASS_ANY;
	} else {
#if FONTMAPPER
		/* otherwise, use MWLOGFONT name and height*/
 		fontclass = select_font(plogfont, fontname);
#else
		if (!name)
			name = MWFONT_SYSTEM_VAR;
		strcpy(fontname, name);
		fontclass = MWLF_CLASS_ANY;
#endif
		height = plogfont->lfHeight;
		if (plogfont->lfUnderline)
			fontattr = MWTF_UNDERLINE;
	}
	height = abs(height);
 
 	if (!fontclass)
 		goto first;
 
	/* use builtin screen fonts, FONT_xxx, if height is 0 */
 	if (height == 0 || fontclass == MWLF_CLASS_ANY ||
	    fontclass == MWLF_CLASS_BUILTIN) {
  		for(i = 0; i < scrinfo.fonts; ++i) {
 			if(!strcmpi(pf[i].name, fontname)) {
  				pf[i].fontsize = pf[i].cfont->height;
				pf[i].fontattr = fontattr;
  				return (PMWFONT)&pf[i];
  			}
  		}
 
		/* return first builtin font*/
		if (height == 0 || fontclass == MWLF_CLASS_BUILTIN)
			goto first;
  	}

#if HAVE_HZK_SUPPORT
        /* Make sure the library is initialized */
	if (hzk_init(psd)) {
		pfont = (PMWFONT)hzk_createfont(name, height, fontattr);
		if(pfont)		
			return pfont;
		fprintf(stderr, "hzk_createfont: %s not found\n", name);
	}
#endif

#if HAVE_FREETYPE_SUPPORT
 	if (fontclass == MWLF_CLASS_ANY || fontclass == MWLF_CLASS_FREETYPE) {
		if (freetype_init(psd)) {
		/* auto antialias for height > 14 for kaffe*/
			if (plogfont && plogfont->lfHeight > 14 &&
				plogfont->lfQuality)
					fontattr |= MWTF_ANTIALIAS;

			pfont = (PMWFONT)freetype_createfont(fontname, height,
					fontattr);
			if(pfont) {
				/* temp kaffe kluge*/
				pfont->fontattr |= FS_FREETYPE;
				return pfont;
			}
 			DPRINTF("freetype_createfont: %s,%d not found\n",
				fontname, height);
		}
  	}
#endif

#if HAVE_T1LIB_SUPPORT
	if (fontclass == MWLF_CLASS_ANY || fontclass == MWLF_CLASS_T1LIB) {
		if (t1lib_init(psd)) {
			pfont = (PMWFONT)t1lib_createfont(fontname, height,
					fontattr);
			if(pfont)
				return pfont;
			DPRINTF("t1lib_createfont: %s,%d not found\n",
				fontname, height);
		}
  	}
#endif

	/* find builtin font closest in height*/
	if(height != 0) {
		fontno = 0;
		height = abs(height);
		fontht = MAX_MWCOORD;
		for(i = 0; i < scrinfo.fonts; ++i) {
			pfont = (PMWFONT)&pf[i];
			GdGetFontInfo(pfont, &fontinfo);
			if(fontht > abs(height-fontinfo.height)) { 
				fontno = i;
				fontht = abs(height-fontinfo.height);
			}
		}
		pf[fontno].fontsize = pf[fontno].cfont->height;
		pf[fontno].fontattr = fontattr;
		return (PMWFONT)&pf[fontno];
	}

first:
	/* Return first builtin font*/
	pf->fontsize = pf->cfont->height;
	pf->fontattr = fontattr;
	return (PMWFONT)&pf[0];
}

/* Set the font size for the passed font*/
MWCOORD
GdSetFontSize(PMWFONT pfont, MWCOORD fontsize)
{
	MWCOORD	oldfontsize = pfont->fontsize;

	pfont->fontsize = fontsize;

	if (pfont->fontprocs->SetFontSize)
	    pfont->fontprocs->SetFontSize(pfont, fontsize);

	return oldfontsize;
}

/* Set the font rotation angle in tenths of degrees for the passed font*/
int
GdSetFontRotation(PMWFONT pfont, int tenthdegrees)
{
	MWCOORD	oldrotation = pfont->fontrotation;

	pfont->fontrotation = tenthdegrees;

	if (pfont->fontprocs->SetFontRotation)
	    pfont->fontprocs->SetFontRotation(pfont, tenthdegrees);
	
	return oldrotation;
}

/*
 * Set/reset font attributes (MWTF_KERNING, MWTF_ANTIALIAS)
 * for the passed font.
 */
int
GdSetFontAttr(PMWFONT pfont, int setflags, int clrflags)
{
	MWCOORD	oldattr = pfont->fontattr;

	pfont->fontattr &= ~clrflags;
	pfont->fontattr |= setflags;

	if (pfont->fontprocs->SetFontAttr)
	    pfont->fontprocs->SetFontAttr(pfont, setflags, clrflags);
	
	return oldattr;
}

/* Unload and deallocate font*/
void
GdDestroyFont(PMWFONT pfont)
{
	if (pfont->fontprocs->DestroyFont)
		pfont->fontprocs->DestroyFont(pfont);
}

/* Return information about a specified font*/
MWBOOL
GdGetFontInfo(PMWFONT pfont, PMWFONTINFO pfontinfo)
{
	if(!pfont || !pfont->fontprocs->GetFontInfo)
		return FALSE;

	return pfont->fontprocs->GetFontInfo(pfont, pfontinfo);
}

/*
 * Convert from one encoding to another
 * Input cc and returned cc is character count, not bytes
 * Return < 0 on error or can't translate
 */
int
GdConvertEncoding(const void *istr, int iflags, int cc, void *ostr, int oflags)
{
	const unsigned char 	*istr8;
	const unsigned short 	*istr16;
	const unsigned long	*istr32;
	unsigned char 		*ostr8;
	unsigned short 		*ostr16;
	unsigned long		*ostr32;
	unsigned int		ch;
	int			icc;
	unsigned short		buf16[512];

	iflags &= MWTF_PACKMASK;
	oflags &= MWTF_PACKMASK;

	/* allow -1 for len with ascii*/
	if(cc == -1 && (iflags == MWTF_ASCII))
		cc = strlen((char *)istr);

	/* first check for utf8 input encoding*/
	if(iflags == MWTF_UTF8) {
		/* we've only got uc16 now so convert to uc16...*/
		cc = utf8_to_utf16((unsigned char *)istr, cc,
			oflags==MWTF_UC16?(unsigned short*) ostr: buf16);

		if(oflags == MWTF_UC16 || cc < 0)
			return cc;

		/* will decode again to requested format (probably ascii)*/
		iflags = MWTF_UC16;
		istr = buf16;
	}

#if HAVE_HZK_SUPPORT
	if(iflags == MWTF_UC16 && oflags == MWTF_ASCII) {
		/* only support uc16 convert to ascii now...*/
		cc = UC16_to_GB( istr, cc, ostr);
		return cc;
	}
#endif

	icc = cc;
	istr8 = istr;
	istr16 = istr;
	istr32 = istr;
	ostr8 = ostr;
	ostr16 = ostr;
	ostr32 = ostr;

	/* Convert between formats.  Note that there's no error
	 * checking here yet.
	 */
	while(--icc >= 0) {
		switch(iflags) {
		default:
			ch = *istr8++;
			break;
		case MWTF_UC16:
			ch = *istr16++;
			break;
		case MWTF_UC32:
			ch = *istr32++;
		}
		switch(oflags) {
		default:
			*ostr8++ = (unsigned char)ch;
			break;
		case MWTF_UC16:
			*ostr16++ = (unsigned short)ch;
			break;
		case MWTF_UC32:
			*ostr32++ = ch;
		}
	}
	return cc;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -