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

📄 devfont.caching.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>

/************/

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 + -