📄 devfont.c
字号:
int icc; unsigned short buf16[512]; iflags &= MWTF_PACKMASK|MWTF_DBCSMASK; oflags &= MWTF_PACKMASK|MWTF_DBCSMASK; /* allow -1 for len with ascii or dbcs*/ 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; cc = 0; 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_XCHAR2B: ch = *istr8++ << 8; ch |= *istr8++; break; case MWTF_UC32: ch = *istr32++; break; case MWTF_DBCS_BIG5: /* Chinese BIG5*/ ch = *istr8++; if (ch >= 0xA1 && ch <= 0xF9 && icc && ((*istr8 >= 0x40 && *istr8 <= 0x7E) || (*istr8 >= 0xA1 && *istr8 <= 0xFE))) { ch = (ch << 8) | *istr8++; --icc; } break; case MWTF_DBCS_EUCCN: /* Chinese EUCCN (GB2312+0x80)*/ ch = *istr8++; if (ch >= 0xA1 && ch <= 0xF7 && icc && *istr8 >= 0xA1 && *istr8 <= 0xFE) { ch = (ch << 8) | *istr8++; --icc; } break; case MWTF_DBCS_EUCKR: /* Korean EUCKR (KSC5601+0x80)*/ ch = *istr8++; if (ch >= 0xA1 && ch <= 0xFE && icc && *istr8 >= 0xA1 && *istr8 <= 0xFE) { ch = (ch << 8) | *istr8++; --icc; } break; case MWTF_DBCS_EUCJP: /* Japanese EUCJP*/ ch = *istr8++; if (ch >= 0xA1 && ch <= 0xFE && icc && *istr8 >= 0xA1 && *istr8 <= 0xFE) { ch = (ch << 8) | *istr8++; --icc; } break; case MWTF_DBCS_JIS: /* Japanese JISX0213*/ ch = *istr8++; if (icc && ( (ch >= 0xA1 && ch <= 0xFE && *istr8 >= 0xA1 && *istr8 <= 0xFE) || (((ch >= 0x81 && ch <= 0x9F) || (ch >= 0xE0 && ch <= 0xEF)) && (*istr8 >= 0x40 && *istr8 <= 0xFC && *istr8 != 0x7F)) )) { ch = (ch << 8) | *istr8++; --icc; } break; } switch(oflags) { default: *ostr8++ = (unsigned char)ch; break; case MWTF_UC16: *ostr16++ = (unsigned short)ch; break; case MWTF_XCHAR2B: *ostr8++ = (unsigned char)(ch >> 8); *ostr8++ = (unsigned char)ch; break; case MWTF_UC32: *ostr32++ = ch; break; } ++cc; } return cc;}/** * Gets the size of some text in a specified font. * * @param pfont The font to measure. Non-NULL. * @param str The string to measure. Non-NULL. * @param cc The length of str. For Asian DBCS encodings, this is * specified in bytes. For all other encodings such as ASCII, * UTF8 and UC16, it is specified in characters. For ASCII * and DBCS encodings, this may be set to -1, and the length * will be calculated automatically. * @param pwidth On return, holds the width of the text. * @param pheight On return, holds the height of the text. * @param pbase On return, holds the baseline of the text. * @param flags Flags specifying the encoding of str and the position of the * text. Specifying the vertical position is mandatory. * The encoding of str defaults to ASCII if not specified. */voidGdGetTextSize(PMWFONT pfont, const void *str, int cc, MWCOORD *pwidth, MWCOORD *pheight, MWCOORD *pbase, MWTEXTFLAGS flags){ const void * text; MWTEXTFLAGS defencoding = pfont->fontprocs->encoding; int force_uc16 = 0; unsigned long buf[256]; /* DBCS handled specially: see comment in GdText*/ if (flags & MWTF_DBCSMASK) { /* force double-byte sequences to UC16 if builtin font only*/ if (pfont->fontprocs->GetTextBits == gen_gettextbits && pfont->fontprocs->DrawText == corefont_drawtext) { defencoding = MWTF_UC16; force_uc16 = 1; } } /* convert encoding if required*/ if((flags & (MWTF_PACKMASK|MWTF_DBCSMASK)) != defencoding) { cc = GdConvertEncoding(str, flags, cc, buf, defencoding); flags &= ~MWTF_PACKMASK; /* keep DBCS bits for gettextsize*/ flags |= defencoding; text = buf; } else text = str; /* use strlen for char count when ascii or dbcs*/ 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*/ if (force_uc16) /* if UC16 conversion forced, string is DBCS*/ dbcs_gettextsize(pfont, text, cc, flags, pwidth, pheight, pbase); else pfont->fontprocs->GetTextSize(pfont, text, cc, flags, pwidth, pheight, pbase);}#if HAVE_FREETYPE_2_SUPPORT/** * Create a new font, from a buffer. * * @param psd Drawing surface. * @param buffer The data to create the font from. This should be an * in-memory copy of a font file. * @param length The length of the buffer, in bytes. * @param format Buffer format, or NULL or "" to auto-detect. * Currently unused, since only FreeType 2 fonts are * currently supported, and FreeType 2 always * autodetects. * @param height The font height in pixels. * @return New font, or NULL on error. */PMWFONTGdCreateFontFromBuffer(PSD psd, const unsigned char *buffer, unsigned length, const char *format, MWCOORD height){ PMWFONT pfont = NULL; //assert(buffer); /* EPRINTF("Nano-X: Font magic = '%c%c%c%c' @ GdCreateFontFromBuffer\n", * (char) buffer[0], (char) buffer[1], (char) buffer[2], (char) buffer[3]); */ /* * If we had multiple font drivers, we'd have to do select one * based on 'format' here. (Suggestion: 'format' is the file * extension - e.g. TTF, PFR, ...) */ if (freetype2_init(psd)) { pfont = (PMWFONT)freetype2_createfontfrombuffer(buffer, length, height); } if (!pfont) EPRINTF("GdCreateFontFromBuffer: create failed.\n"); return pfont;}/** * Create a new font, which is a copy of an old font. * * @param psd Drawing surface. * @param psrcfont Font to copy from. * @param fontsize Size of new font, or 0 for unchanged. * @return New font. */PMWFONTGdDuplicateFont(PSD psd, PMWFONT psrcfont, MWCOORD fontsize){ //assert(psd); //assert(psrcfont); if (psrcfont->fontprocs->Duplicate) return psrcfont->fontprocs->Duplicate(psrcfont, fontsize); return psrcfont;}#endif /*HAVE_FREETYPE_2_SUPPORT*//** * UTF-8 to UTF-16 conversion. Surrogates are handeled properly, e.g. * a single 4-byte UTF-8 character is encoded into a surrogate pair. * On the other hand, if the UTF-8 string contains surrogate values, this * is considered an error and returned as such. * * The destination array must be able to hold as many Unicode-16 characters * as there are ASCII characters in the UTF-8 string. This in case all UTF-8 * characters are ASCII characters. No more will be needed. * * This function will also accept Java's variant of UTF-8. This encodes * U+0000 as two characters rather than one, so the UTF-8 does not contain * any zeroes. * * @author Copyright (c) 2000 Morten Rolland, Screen Media * * @param utf8 Input string in UTF8 format. * @param cc Number of bytes to convert. * @param unicode16 Destination buffer. * @return Number of characters converted, or -1 if input is not * valid UTF8. */static intutf8_to_utf16(const unsigned char *utf8, int cc, unsigned short *unicode16){ int count = 0; unsigned char c0, c1; unsigned long scalar; while(--cc >= 0) { c0 = *utf8++; /*DPRINTF("Trying: %02x\n",c0);*/ if ( c0 < 0x80 ) { /* Plain ASCII character, simple translation :-) */ *unicode16++ = c0; count++; continue; } if ( (c0 & 0xc0) == 0x80 ) /* Illegal; starts with 10xxxxxx */ return -1; /* c0 must be 11xxxxxx if we get here => at least 2 bytes */ scalar = c0; if(--cc < 0) return -1; c1 = *utf8++; /*DPRINTF("c1=%02x\n",c1);*/ if ( (c1 & 0xc0) != 0x80 ) /* Bad byte */ return -1; scalar <<= 6; scalar |= (c1 & 0x3f); if ( !(c0 & 0x20) ) { /* Two bytes UTF-8 */ if ( (scalar != 0) && (scalar < 0x80) ) return -1; /* Overlong encoding */ *unicode16++ = scalar & 0x7ff; count++; continue; } /* c0 must be 111xxxxx if we get here => at least 3 bytes */ if(--cc < 0) return -1; c1 = *utf8++; /*DPRINTF("c1=%02x\n",c1);*/ if ( (c1 & 0xc0) != 0x80 ) /* Bad byte */ return -1; scalar <<= 6; scalar |= (c1 & 0x3f); if ( !(c0 & 0x10) ) { /*DPRINTF("####\n");*/ /* Three bytes UTF-8 */ if ( scalar < 0x800 ) return -1; /* Overlong encoding */ if ( scalar >= 0xd800 && scalar < 0xe000 ) return -1; /* UTF-16 high/low halfs */ *unicode16++ = scalar & 0xffff; count++; continue; } /* c0 must be 1111xxxx if we get here => at least 4 bytes */ c1 = *utf8++; if(--cc < 0) return -1; /*DPRINTF("c1=%02x\n",c1);*/ if ( (c1 & 0xc0) != 0x80 ) /* Bad byte */ return -1; scalar <<= 6; scalar |= (c1 & 0x3f); if ( !(c0 & 0x08) ) { /* Four bytes UTF-8, needs encoding as surrogates */ if ( scalar < 0x10000 ) return -1; /* Overlong encoding */ scalar -= 0x10000; *unicode16++ = ((scalar >> 10) & 0x3ff) + 0xd800; *unicode16++ = (scalar & 0x3ff) + 0xdc00; count += 2; continue; } return -1; /* No support for more than four byte UTF-8 */ } return count;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -