📄 devfont.c
字号:
TT_Get_Glyph_Metrics (pf->glyph, &metrics);
if ((pf->fontattr&MWTF_KERNING) && pf->can_kern) {
x += compute_kernval(pf, curchar) / 64;
}
x += metrics.advance / 64;
/* Kerning point syndrome avoidance */
if (pf->last_pen_pos > x)
x = pf->last_pen_pos;
pf->last_pen_pos = x;
pf->last_glyph_code = curchar;
}
*pwidth = x;
*pheight = (((properties.horizontal->Ascender *
imetrics.y_scale)/ 0x10000) >> 6) -
(((properties.horizontal->Descender *
imetrics.y_scale)/ 0x10000) >> 6);
/* FIXME: is it what's required ?? */
*pbase = (((-properties.horizontal->Descender) *
imetrics.y_scale)/ 0x10000) >> 6;
}
static void
freetype_destroyfont(PMWFONT pfont)
{
PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont;
TT_Close_Face(pf->face);
free(pf);
}
static void
freetype_setfontsize(PMWFONT pfont, MWCOORD fontsize)
{
PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont;
pf->fontsize = fontsize;
/* We want real pixel sizes ... not points ...*/
TT_Set_Instance_PixelSizes( pf->instance, pf->fontsize,
pf->fontsize, pf->fontsize * 64 );
#if 0
/* set charsize (convert to points for freetype)*/
TT_Set_Instance_CharSize (pf->instance,
((pf->fontsize * 72 + 96/2) / 96) * 64);
#endif
}
static void
freetype_setfontrotation(PMWFONT pfont, int tenthdegrees)
{
PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont;
float angle;
pf->fontrotation = tenthdegrees;
/* Build the rotation matrix with the given angle */
TT_Set_Instance_Transform_Flags (pf->instance, TRUE, FALSE);
angle = pf->fontrotation * M_PI / 1800;
pf->matrix.yy = (TT_Fixed) (cos (angle) * (1 << 16));
pf->matrix.yx = (TT_Fixed) (sin (angle) * (1 << 16));
pf->matrix.xx = pf->matrix.yy;
pf->matrix.xy = -pf->matrix.yx;
}
#endif /* HAVE_FREETYPE_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.
*
* Copyright (c) 2000 Morten Rolland, Screen Media
*/
static int
utf8_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 < 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;
}
#if HAVE_HZK_SUPPORT
/* UniCode-16 (MWTF_UC16) to GB(MWTF_ASCII) Chinese Characters conversion.
* a single 2-byte UC16 character is encoded into a surrogate pair.
* return -1 ,if error;
* The destination array must be able to hold as many
* as there are Unicode-16 characters.
*
* Copyright (c) 2000 Tang Hao (TownHall)(tang_hao@263.net).
*/
static int
UC16_to_GB(const unsigned char *uc16, int cc, unsigned char *ascii)
{
FILE* fp;
char buffer[256];
unsigned char *uc16p;
int i=0,j=0, k;
unsigned char *filebuffer;
unsigned short *uc16pp,*table;
unsigned short uc16px;
int length=31504;
if (use_big5)
length=54840;
uc16p=(unsigned char *) uc16;
uc16pp=(unsigned short *) uc16;
strcpy(buffer,HZK_FONT_DIR);
if (use_big5)
strcat(buffer,"/BG2UBG.KU");
else
strcat(buffer,"/UGB2GB.KU");
if(!(fp = fopen(buffer, "rb")))
{
fprintf (stderr, "Error.\nThe %s file can not be found!\n",buffer);
return -1;
}
filebuffer= (unsigned char *)malloc ( length);
if(fread(filebuffer, sizeof(char),length, fp) < length) {
fprintf (stderr, "Error in reading ugb2gb.ku file!\n");
fclose(fp);
return -1;
}
fclose(fp);
if (use_big5)
{
table=(unsigned short *)filebuffer;
while(1)
{
if(j>=cc)
{
ascii[i]=0;
break;
}
uc16px=*uc16pp;
if((uc16px)<=0x00ff)
{
ascii[i]=(char)(*uc16pp);
i++;
}
else
{
ascii[i]=0xa1; ascii[i+1]=0x40;
for (k=0; k<13710; k++)
{
if (*(table+(k*2+1))==(uc16px))
{
ascii[i]=(char)((*(table+(k*2)) & 0xff00) >> 8);
ascii[i+1]=(char)(*(table+(k*2)) & 0x00ff);
break;
}
}
i+=2;
}
uc16pp++; j++;
}
}
else
{
while(1)
{
if(j>=cc)
{
ascii[i]=0;
break;
}
if((*((uc16p)+j)==0)&&(*((uc16p)+j+1)==0))
{
ascii[i]=0;
break;
}
else
{
if(*((uc16p)+j+1)==0)
{
ascii[i]=*((uc16p)+j);
i++;
j+=2;
}
else
{
/* to find the place of unicode charater .二分法匹配*/
{
int p1=0,p2=length-4,p;
unsigned int c1,c2,c,d;
c1=((unsigned int )filebuffer[p1])*0x100+(filebuffer[p1+1]);
c2=((unsigned int )filebuffer[p2])*0x100+(filebuffer[p2+1]);
d=((unsigned int )*((uc16p)+j))*0x100+*((uc16p)+j+1);
if(c1==d)
{
ascii[i]=filebuffer[p1+2];
ascii[i+1]=filebuffer[p1+3];
goto findit;
}
if(c2==d)
{
ascii[i]=filebuffer[p2+2];
ascii[i+1]=filebuffer[p2+3];
goto findit;
}
while(1)
{
p=(((p2-p1)/2+p1)>>2)<<2;
c=((unsigned int )filebuffer[p])*0x100+(filebuffer[p+1]);
if(d==c) /* find it*/
{
ascii[i]=filebuffer[p+2];
ascii[i+1]=filebuffer[p+3];
break;
}
else if(p2<=p1+4) /* can't find.*/
{
ascii[i]='.'; /* ((uc16p)+j);*/
ascii[i+1]='.'; /* ((uc16p)+j+1);*/
break;
}
else if(d<c)
{
p2=p;
c2=c;
}
else
{
p1=p;
c1=c;
}
}
}
findit:
i+=2;
j+=2;
}
}
}
}
free(filebuffer);
return i;
}
/************************** functions definition ******************************/
static int hzk_id( PMWHZKFONT pf )
{
switch(pf->font_height)
{
case 12:
return 0;
case 16: default:
return 1;
}
}
/* This function get Chinese font info from etc file.*/
static MWBOOL GetCFontInfo( PMWHZKFONT pf )
{
int charset;
if (use_big5)
charset=(13094+408);
else
charset=8178;
CFont[hzk_id(pf)].width = pf->cfont_width;
pf->CFont.width = pf->cfont_width;
CFont[hzk_id(pf)].height = pf->font_height;
pf->CFont.height = pf->font_height;
CFont[hzk_id(pf)].size = ((pf->CFont.width + 7) / 8) *
pf->CFont.height * charset;
pf->CFont.size = ((pf->CFont.width + 7) / 8) * pf->CFont.height * charset;
if(pf->CFont.size < charset * 8)
return FALSE;
strcpy(CFont[hzk_id(pf)].file,HZK_FONT_DIR);
strcpy(pf->CFont.file,HZK_FONT_DIR);
if(pf->font_height==16)
{
strcat(CFont[hzk_id(pf)].file,"/hzk16");
strcat(pf->CFont.file,"/hzk16");
}
else
{
strcat(CFont[hzk_id(pf)].file,"/hzk12");
strcat(pf->CFont.file,"/hzk12");
}
if (use_big5)
{
CFont[hzk_id(pf)].file[strlen(pf->CFont.file)-3]+=use_big5;
pf->CFont.file[strlen(pf->CFont.file)-3]+=use_big5;
}
return TRUE;
}
/* This function get ASCII font info from etc file.*/
static MWBOOL GetAFontInfo( PMWHZKFONT pf )
{
AFont[hzk_id(pf)].width = pf->afont_width;
pf->AFont.width = pf->afont_width;
AFont[hzk_id(pf)].height = pf->font_height;
pf->AFont.height = pf->font_height;
AFont[hzk_id(pf)].size = ((pf->AFont.width + 7) / 8) *
pf->AFont.height * 255;
pf->AFont.size = ((pf->AFont.width + 7) / 8) * pf->AFont.height * 255;
if(pf->AFont.size < 255 * 8)
return FALSE;
strcpy(AFont[hzk_id(pf)].file,HZK_FONT_DIR);
strcpy(pf->AFont.file,HZK_FONT_DIR);
if(pf->font_height==16)
{
strcat(AFont[hzk_id(pf)].file,"/asc16");
strcat(pf->AFont.file,"/asc16");
}
else
{
strcat(AFont[hzk_id(pf)].file,"/asc12");
strcat(pf->AFont.file,"/asc12");
}
return TRUE;
}
/* This function load system font into memory.*/
static MWBOOL LoadFont( PMWHZKFONT pf )
{
FILE* fp;
if(!GetCFontInfo(pf))
{
fprintf (stderr, "Get Chinese HZK font info failure!\n");
return FALSE;
}
if(CFont[hzk_id(pf)].pFont == NULL) /* check font cache*/
{
/* Allocate system memory for Chinese font.*/
if( !(CFont[hzk_id(pf)].pFont = (char *)malloc(pf->CFont.size)) )
{
fprintf (stderr, "Allocate memory for Chinese HZK font failure.\n");
return FALSE;
}
/* Open font file and read information to the system memory.*/
fprintf (stderr, "Loading Chinese HZK font from file(%s)..." ,pf->CFont.file);
if(!(fp = fopen(CFont[hzk_id(pf)].file, "rb")))
{
fprintf (stderr, "Error.\nThe Chinese HZK font file can not be found!\n");
return FALSE;
}
if(fread(CFont[hzk_id(pf)].pFont, sizeof(char), pf->CFont.size, fp) < pf->CFont.size)
{
fprintf (stderr, "Error in reading Chinese HZK font file!\n");
fclose(fp);
return FALSE;
}
fclose(fp);
CFont[hzk_id(pf)].use_count=0;
fprintf (stderr, "done.\n" );
}
cfont_address = CFont[hzk_id(pf)].pFont;
pf->cfont_address = CFont[hzk_id(pf)].pFont;
pf->CFont.pFont = CFont[hzk_id(pf)].pFont;
CFont[hzk_id(pf)].use_count++;
if(!GetAFontInfo(pf))
{
fprintf (stderr, "Get ASCII HZK font info failure!\n");
return FALSE;
}
if(AFont[hzk_id(pf)].pFont == NULL) /* check font cache*/
{
/* Allocate system memory for ASCII font.*/
if( !(AFont[hzk_id(pf)].pFont = (char *)malloc(pf->AFont.size)) )
{
fprintf (stderr, "Allocate memory for ASCII HZK font failure.\n");
free(CFont[hzk_id(pf)].pFont);
CFont[hzk_id(pf)].pFont = NULL;
return FALSE;
}
/* Load ASCII font information to the near memory.*/
fprintf (stderr, "Loading ASCII HZK font..." );
if(!(fp = fopen(AFont[hzk_id(pf)].file, "rb")))
{
fprintf (stderr, "Error.\nThe ASCII HZK font file can not be found!\n");
return FALSE;
}
if(fread(AFont[hzk_id(pf)].pFont, sizeof(char), pf->AFont.size, fp) < pf->AFont.size)
{
fprintf (stderr, "Error in reading ASCII HZK font file!\n");
fclose(fp);
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -