📄 devfont.c
字号:
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#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 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; 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 intt1lib_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 PMWT1LIBFONTt1lib_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 voidt1lib_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 MWBOOLt1lib_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 voidt1lib_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 voidt1lib_destroyfont(PMWFONT pfont){ PMWT1LIBFONT pf = (PMWT1LIBFONT)pfont; T1_DeleteAllSizes(pf->fontid); free(pf);}#endif /* HAVE_T1LIB_SUPPORT*/#if HAVE_FREETYPE_SUPPORTstatic OUTPIXELVAL gray_palette[5];static intfreetype_init(PSD psd){ static int inited = 0; if (inited) return 1; /* Init freetype library */ if (TT_Init_FreeType (&engine) != TT_Err_Ok) { return 0; } /* Init kerning extension */ if (TT_Init_Kerning_Extension (engine) != TT_Err_Ok) return 0; inited = 1; return 1;}static PMWFREETYPEFONTfreetype_createfont(const char *name, MWCOORD height, int attr){ PMWFREETYPEFONT pf; unsigned short i, n; unsigned short platform, encoding; TT_Face_Properties properties; char * p; char fontname[128]; /* check for pathname prefix*/ if (strchr(name, '/') != NULL) strcpy(fontname, name); else { strcpy(fontname, FREETYPE_FONT_DIR); strcat(fontname, "/"); strcat(fontname, name); } /* check for extension*/ if ((p = strrchr(fontname, '.')) == NULL || strcmp(p, ".ttf") != 0) { strcat(fontname, ".ttf"); } /* allocate font structure*/ pf = (PMWFREETYPEFONT)calloc(sizeof(MWFREETYPEFONT), 1); if (!pf) return NULL; pf->fontprocs = &freetype_procs; /* Load face */ if (TT_Open_Face (engine, fontname, &pf->face) != TT_Err_Ok) goto out; /* Load first kerning table */ pf->can_kern = TRUE; if (TT_Load_Kerning_Table (pf->face, 0) != TT_Err_Ok) pf->can_kern = FALSE; else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -