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

📄 devfont.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 5 页
字号:
}

/* Get the width and height of passed text string in the passed font*/
void
GdGetTextSize(PMWFONT pfont, const void *str, int cc, MWCOORD *pwidth,
	MWCOORD *pheight, MWCOORD *pbase, int flags)
{
	const void *	text;
	unsigned long	buf[256];
	int		defencoding = pfont->fontprocs->encoding;

	/* convert encoding if required*/
	if((flags & MWTF_PACKMASK) != defencoding) {
		cc = GdConvertEncoding(str, flags, cc, buf, defencoding);
		flags &= ~MWTF_PACKMASK;
		flags |= defencoding;
		text = buf;
	} else text = str;

	if(cc == -1 && (flags & MWTF_PACKMASK) == MWTF_ASCII)
		cc = strlen((char *)str);

	if(cc <= 0 || !pfont->fontprocs->GetTextSize) {
		*pwidth = *pheight = *pbase = 0;
		return;
	}

	/* calc height and width of string*/
	pfont->fontprocs->GetTextSize(pfont, text, cc, pwidth, pheight, pbase);
}

/* Draw a text string at a specifed coordinates in the foreground color
 * (and possibly the background color), applying clipping if necessary.
 * The background color is only drawn if the gr_usebg flag is set.
 * Use the current font.
 */
void
GdText(PSD psd, MWCOORD x, MWCOORD y, const void *str, int cc, int flags)
{
	const void *	text;
	unsigned long	buf[256];
	int		defencoding = gr_pfont->fontprocs->encoding;

	/* convert encoding if required*/
	if((flags & MWTF_PACKMASK) != defencoding) {
		cc = GdConvertEncoding(str, flags, cc, buf, defencoding);
		flags &= ~MWTF_PACKMASK;
		flags |= defencoding;
		text = buf;
	} else text = str;

	if(cc == -1 && (flags & MWTF_PACKMASK) == MWTF_ASCII)
		cc = strlen((char *)str);

	if(cc <= 0 || !gr_pfont->fontprocs->DrawText)
		return;

	/* draw text string*/
	gr_pfont->fontprocs->DrawText(gr_pfont, psd, x, y, text, cc, flags);
}

/*
 * Draw ascii text using COREFONT type font.
 */
void
corefont_drawtext(PMWFONT pfont, PSD psd, MWCOORD x, MWCOORD y,
	const void *text, int cc, int flags)
{
	const unsigned char *str = text;
	MWCOORD		width;			/* width of text area */
	MWCOORD 	height;			/* height of text area */
	MWCOORD		base;			/* baseline of text*/
	MWCOORD		startx, starty;
						/* bitmap for characters */
	MWIMAGEBITS bitmap[MAX_CHAR_HEIGHT*MAX_CHAR_WIDTH/MWIMAGE_BITSPERIMAGE];

	pfont->fontprocs->GetTextSize(pfont, str, cc, &width, &height, &base);
	
	if(flags & MWTF_BASELINE)
		y -= base;
	else if(flags & MWTF_BOTTOM)
		y -= (height - 1);
	startx = x;
	starty = y + base;

	switch (GdClipArea(psd, x, y, x + width - 1, y + height - 1)) {
	case CLIP_VISIBLE:
		/*
		 * For size considerations, there's no low-level text
		 * draw, so we've got to draw all text
		 * with per-point clipping for the time being
		if (gr_usebg)
			psd->FillRect(psd, x, y, x + width - 1, y + height - 1,
				gr_background);
		psd->DrawText(psd, x, y, str, cc, gr_foreground, pfont);
		GdFixCursor(psd);
		return;
		*/
		break;

	case CLIP_INVISIBLE:
		return;
	}

	/* Get the bitmap for each character individually, and then display
	 * them using clipping for each one.
	 */
	while (--cc >= 0 && x < psd->xvirtres) {
		unsigned int ch = *str++;
#if HAVE_BIG5_SUPPORT
		/* chinese big5 decoding*/
		if (ch >= 0xA1 && ch <= 0xF9 && cc >= 1 &&
			((*str >= 0x40 && *str <= 0x7E) ||
			 (*str >= 0xA1 && *str <= 0xFE)) ) {
				ch = (ch << 8) | *str++;
				--cc;
		}
#endif
#if HAVE_GB2312_SUPPORT
		/* chinese gb2312 decoding*/
		if (ch >= 0xA1 && ch < 0xF8 && cc >= 1 &&
			*str >= 0xA1 && *str < 0xFF) {
				ch = (ch << 8) | *str++;
				--cc;
		}
#endif
#if HAVE_KSC5601_SUPPORT
		/* Korean KSC5601 decoding */
		if (ch >= 0xA1 && ch <= 0xFE && cc >= 1 &&
			 (*str >= 0xA1 && *str <= 0xFE)) {
				ch = (ch << 8) | *str++;
				--cc;
		}
#endif
		pfont->fontprocs->GetTextBits(pfont, ch, bitmap, &width,
			&height, &base);

		/* note: change to bitmap*/
		GdBitmap(psd, x, y, width, height, bitmap);
		x += width;
	}

	if (pfont->fontattr & MWTF_UNDERLINE)
		GdLine(psd, startx, starty, x, starty, FALSE);

	GdFixCursor(psd);
}

#if HAVE_T1LIB_SUPPORT | HAVE_FREETYPE_SUPPORT
/*
 * Produce blend table from src and dst based on passed alpha table
 * Used because we don't quite yet have GdArea with alphablending,
 * so we pre-blend fg/bg colors for fade effect.
 */
static void
alphablend(PSD psd, OUTPIXELVAL *out, MWPIXELVAL src, MWPIXELVAL dst,
	unsigned char *alpha, int count)
{
	unsigned int	a, d;
	unsigned char	r, g, b;
	MWCOLORVAL	palsrc, paldst;
	extern MWPALENTRY gr_palette[256];

	while (--count >= 0) {
	    a = *alpha++;

#define BITS(pixel,shift,mask)	(((pixel)>>shift)&(mask))
	    if(a == 0)
		*out++ = dst;
	    else if(a == 255)
		*out++ = src;
	    else 
		switch(psd->pixtype) {
	        case MWPF_TRUECOLOR0888:
	        case MWPF_TRUECOLOR888:
		    d = BITS(dst, 16, 0xff);
		    r = (unsigned char)(((BITS(src, 16, 0xff) - d)*a)>>8) + d;
		    d = BITS(dst, 8, 0xff);
		    g = (unsigned char)(((BITS(src, 8, 0xff) - d)*a)>>8) + d;
		    d = BITS(dst, 0, 0xff);
		    b = (unsigned char)(((BITS(src, 0, 0xff) - d)*a)>>8) + d;
		    *out++ = (r << 16) | (g << 8) | b;
		    break;

	        case MWPF_TRUECOLOR565:
		    d = BITS(dst, 11, 0x1f);
		    r = (unsigned char)(((BITS(src, 11, 0x1f) - d)*a)>>8) + d;
		    d = BITS(dst, 5, 0x3f);
		    g = (unsigned char)(((BITS(src, 5, 0x3f) - d)*a)>>8) + d;
		    d = BITS(dst, 0, 0x1f);
		    b = (unsigned char)(((BITS(src, 0, 0x1f) - d)*a)>>8) + d;
		    *out++ = (r << 11) | (g << 5) | b;
		    break;

	        case MWPF_TRUECOLOR555:
		    d = BITS(dst, 10, 0x1f);
		    r = (unsigned char)(((BITS(src, 10, 0x1f) - d)*a)>>8) + d;
		    d = BITS(dst, 5, 0x1f);
		    g = (unsigned char)(((BITS(src, 5, 0x1f) - d)*a)>>8) + d;
		    d = BITS(dst, 0, 0x1f);
		    b = (unsigned char)(((BITS(src, 0, 0x1f) - d)*a)>>8) + d;
		    *out++ = (r << 10) | (g << 5) | b;
		    break;

	        case MWPF_TRUECOLOR332:
		    d = BITS(dst, 5, 0x07);
		    r = (unsigned char)(((BITS(src, 5, 0x07) - d)*a)>>8) + d;
		    d = BITS(dst, 2, 0x07);
		    g = (unsigned char)(((BITS(src, 2, 0x07) - d)*a)>>8) + d;
		    d = BITS(dst, 0, 0x03);
		    b = (unsigned char)(((BITS(src, 0, 0x03) - d)*a)>>8) + d;
		    *out++ = (r << 5) | (g << 2) | b;
		    break;

	        case MWPF_TRUECOLOR233:
		    d = BITS(dst, 0, 0x07);
		    r = (unsigned char)(((BITS(src, 0, 0x07) - d)*a)>>8) + d;
		    d = BITS(dst, 3, 0x07);
		    g = (unsigned char)(((BITS(src, 3, 0x07) - d)*a)>>8) + d;
		    d = BITS(dst, 6, 0x03);
		    b = (unsigned char)(((BITS(src, 6, 0x03) - d)*a)>>8) + d;
		    *out++ = (b << 6) | (g << 3) | r;
		    break;

	        case MWPF_PALETTE:
		    /* reverse lookup palette entry for blend ;-)*/
		    palsrc = GETPALENTRY(gr_palette, src);
		    paldst = GETPALENTRY(gr_palette, dst);
		    d = REDVALUE(paldst);
		    r = (unsigned char)(((REDVALUE(palsrc) - d)*a)>>8) + d;
		    d = GREENVALUE(paldst);
		    g = (unsigned char)(((GREENVALUE(palsrc) - d)*a)>>8) + d;
		    d = BLUEVALUE(paldst);
		    b = (unsigned char)(((BLUEVALUE(palsrc) - d)*a)>>8) + d;
		    *out++ = GdFindNearestColor(gr_palette, (int)psd->ncolors,
				MWRGB(r, g, b));
		    break;
	  	}
	}
}
#endif /*HAVE_T1LIB_SUPPORT | HAVE_FREETYPE_SUPPORT*/

#if HAVE_T1LIB_SUPPORT
/* contributed by Vidar Hokstad*/

static int
t1lib_init(PSD psd)
{
	char **encoding;
	static int inited = 0;

	if (inited)
		return 1;

	T1_SetBitmapPad(8);
	if (!T1_InitLib(0))
		return 0;

	/* set default Latin1 encoding*/
	encoding = T1_LoadEncoding("IsoLatin1.enc");
	T1_SetDefaultEncoding(encoding);

#ifdef T1LIB_USE_AA_HIGH	 
	T1_AASetLevel(T1_AA_HIGH);
#else
	T1_AASetLevel(T1_AA_LOW);
#endif	 
#if 0
	/* kluge: this is required if 16bpp drawarea driver is used*/
	if(psd->bpp == 16)
		T1_AASetBitsPerPixel(16);
	else
#endif
		T1_AASetBitsPerPixel(sizeof(MWPIXELVAL)*8);

	inited = 1;
	return 1;
}

static PMWT1LIBFONT
t1lib_createfont(const char *name, MWCOORD height, int attr)
{
	PMWT1LIBFONT	pf;
	int		id;
	char *		p;
	char		buf[256];

	/* match name against t1 font id's from t1 font database*/
	for(id=0; id<T1_Get_no_fonts(); ++id) {
		strncpy(buf, T1_GetFontFileName(id), sizeof(buf));

		/* remove extension*/
		for(p=buf; *p; ++p) {
			if(*p == '.') {
				*p = 0;
				break;
			}
		}

		if(!strcmpi(name, buf)) {
			/* allocate font structure*/
			pf = (PMWT1LIBFONT)calloc(sizeof(MWT1LIBFONT), 1);
			if (!pf)
				return NULL;
			pf->fontprocs = &t1lib_procs;
			GdSetFontSize((PMWFONT)pf, height);
			GdSetFontRotation((PMWFONT)pf, 0);
			GdSetFontAttr((PMWFONT)pf, attr, 0);
			pf->fontid = id;
			return pf;
		}
	}
	return NULL;
}

/*
 * Draw ascii text string using T1LIB type font
 */
static void
t1lib_drawtext(PMWFONT pfont, PSD psd, MWCOORD x, MWCOORD y,
	const void *text, int cc, int flags)
{
	PMWT1LIBFONT	pf = (PMWT1LIBFONT)pfont;
	const unsigned char *str = text;
   	MWCOORD		width;			/* width of text area */
	MWCOORD 	height;			/* height of text area */
	MWCOORD		underliney;
        GLYPH * g; /* T1lib glyph structure. Memory handling by T1lib */
#ifdef T1LIB_USE_AA_HIGH   
        OUTPIXELVAL	gvals[17];

        /* Blending array for antialiasing. The steeper the values increase
	 * near the end, the sharper the characters look, but also more jagged
	 */
        static unsigned char blend[17] = {
	   0x00, 0x00, 0x04, 0x0c, 0x10, 0x14, 0x18, 0x20,
	   0x30, 0x38, 0x40, 0x50, 0x70, 0x80, 0xa0, 0xc0, 0xff
	};
#else   
        OUTPIXELVAL	gvals[5];
        static unsigned char blend[5] = { 0x00, 0x44, 0x88, 0xcc, 0xff };
#endif   

        /* Check if we should throw out some fonts */

        if (pf->fontattr&MWTF_ANTIALIAS) {
#ifdef T1LIB_USE_AA_HIGH      
	   alphablend(psd, gvals, gr_foreground, gr_background, blend, 17);
           T1_AAHSetGrayValues(gvals);
#else      
	   alphablend(psd, gvals, gr_foreground, gr_background, blend, 5);
           T1_AASetGrayValues(gvals[0],gvals[1],gvals[2],gvals[3],gvals[4]);
#endif
	   g = T1_AASetString(pf->fontid,(char *)str,cc,0,
		(pf->fontattr&MWTF_KERNING)? T1_KERNING: 0,
		pf->fontsize * 1.0, 0);

	   if (g && g->bits) {
	      /*MWPIXELVAL save = gr_background;*/
	      width = g->metrics.rightSideBearing - g->metrics.leftSideBearing;
	      height = g->metrics.ascent - g->metrics.descent;

	      if(flags & MWTF_BASELINE)
		y -= g->metrics.ascent;
	      else if(flags & MWTF_BOTTOM)
		y -= (height - 1);
	      underliney = y + g->metrics.ascent;

	      /* FIXME: Looks damn ugly if usebg is false.
	       * Will be handled when using alphablending in GdArea...
	       */
	      /* clipping handled in GdArea*/
	      /*FIXME kluge for transparency*/
	      /*gr_background = gr_foreground + 1;*/
	      /*gr_usebg = 0;*/
	      GdArea(psd,x,y, width, height, g->bits, MWPF_PIXELVAL);
	      /*gr_background = save;*/

	      if (pf->fontattr & MWTF_UNDERLINE)
		   GdLine(psd, x, underliney, x+width, underliney, FALSE);

	   }
	} else {
	   /* Do non-aa drawing */
	   g = T1_SetString(pf->fontid,(char *)str,cc,0,
			(pf->fontattr&MWTF_KERNING)? T1_KERNING: 0,
			pf->fontsize * 1.0, 0);

	   if (g && g->bits) {
	      unsigned char * b;
	      int xoff;
	      int maxy;
	      int xmod;
	      
	      /* I'm sure this sorry excuse for a bitmap rendering routine can
	       * be optimized quite a bit ;)
	       */
	      width = g->metrics.rightSideBearing - g->metrics.leftSideBearing;
	      height = g->metrics.ascent - g->metrics.descent;

	      if(flags & MWTF_BASELINE)
		y -= g->metrics.ascent;
	      else if(flags & MWTF_BOTTOM)
		y -= (height - 1);
	      underliney = y + g->metrics.ascent;
	      
	      b = g->bits;
	      maxy = y + height;
	      
/*	      if ((x + width) > psd->xvirtres) {
		 xmod = (x + width - psd->xvirtres + 7) >> 3;
		 width = width + x + width - psd->xvirtres;
	      } else xmod = 0;
*/
	      xmod = 0;
	      while (y < maxy) {
		 unsigned char data;
		 xoff = 0;
		 while (xoff < width ) {
		    if (!(xoff % 8)) {
		       data = *b;
		       b++;
		    }
		    
		    if (GdClipPoint(psd, x+xoff,y)) {
		       if (gr_usebg) {
	 		  psd->DrawPixel(psd,x+xoff,y,
			      data & (1 << (xoff % 8)) ?
			            gr_foreground : gr_background);
		       } else if (data & (1 << (xoff % 8))) {
			  psd->DrawPixel(psd,x+xoff,y, gr_foreground);
		       }
		    }
		    xoff++;
		 }
		 b += xmod;
		 y++;
	      }
	      if (pf->fontattr & MWTF_UNDERLINE)
		   GdLine(psd, x, underliney, x+xoff, underliney, FALSE);
	   }
        }

   if (g && g->bits) {
	   /* Save some memory */
	   free(g->bits);
           g->bits = 0; /* Make sure T1lib doesnt try to free it again */
   }

   GdFixCursor(psd);
}

static MWBOOL
t1lib_getfontinfo(PMWFONT pfont, PMWFONTINFO pfontinfo)
{
	int	i;
	MWCOORD	width, height, baseline;

	/* FIXME, guess all sizes*/
	GdGetTextSize(pfont, "A", 1, &width, &height, &baseline, MWTF_ASCII);
	pfontinfo->height = height;
	pfontinfo->maxwidth = width;
	pfontinfo->baseline = 0;
	pfontinfo->firstchar = 32;
	pfontinfo->lastchar = 255;
	pfontinfo->fixed = TRUE;
	for(i=0; i<256; ++i)
		pfontinfo->widths[i] = width;
	return TRUE;
}

/* Get the width and height of passed text string in the current font*/
static void
t1lib_gettextsize(PMWFONT pfont, const void *text, int cc,
	MWCOORD *pwidth, MWCOORD *pheight, MWCOORD *pbase)
{
	PMWT1LIBFONT		pf = (PMWT1LIBFONT)pfont;
	const unsigned char *	str = text;
	GLYPH *			g;

	g = T1_SetString(pf->fontid, (char *)str, cc, 0,
			(pf->fontattr&MWTF_KERNING)? T1_KERNING: 0, pf->fontsize * 1.0, 0);
	*pwidth = g->metrics.rightSideBearing - g->metrics.leftSideBearing;
	*pheight = g->metrics.ascent - g->metrics.descent;
	if(g && g->bits) {
		free(g->bits);
		g->bits = 0;
	}
#if 0
	BBox 			b;

	/* FIXME. Something is *VERY* wrong here */
	b = T1_GetStringBBox(pf->fontid, str, cc, 0, (pf->fontattr&MWTF_KERNING)?T1_KERNING:0);

	DPRINTF("b.urx = %d, b.llx = %d\n",b.urx, b.llx);
	DPRINTF("b.ury = %d, b.lly = %d\n",b.ury, b.lly);
	*pwidth = (b.urx - b.llx);
	*pheight = (b.lly - b.ury);
#endif
}

static void
t1lib_destroyfont(PMWFONT pfont)
{
	PMWT1LIBFONT	pf = (PMWT1LIBFONT)pfont;

	T1_DeleteAllSizes(pf->fontid);
	free(pf);
}

⌨️ 快捷键说明

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