📄 devfont.caching.c
字号:
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);/*static void hzk_gettextbits(PMWFONT pfont, int ch, IMAGEBITS *retmap, MWCOORD *pwidth, MWCOORD *pheight, MWCOORD *pbase);*/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);/*static void hzk_setfontrotation(PMWFONT pfont, int tenthdegrees);*/ /* 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 intUC16_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. */PMWFONTGdSetFont(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. */PMWFONTGdCreateFont(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; printf("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*/MWCOORDGdSetFontSize(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*/intGdSetFontRotation(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. */intGdSetFontAttr(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*/voidGdDestroyFont(PMWFONT pfont){ if (pfont->fontprocs->DestroyFont) pfont->fontprocs->DestroyFont(pfont);}/* Return information about a specified font*/MWBOOLGdGetFontInfo(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 */intGdConvertEncoding(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;}/* Get the width and height of passed text string in the passed font*/voidGdGetTextSize(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. */voidGdText(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. */voidcorefont_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 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 voidalphablend(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -