Fixed for DBCS(cp932/cp949) codepage conversion.

Implemented cp932 handling partly(but still incomplete).
Added supporting multiple fonts for DBCS handling.
This commit is contained in:
Hidenori Takeshima 2000-08-15 12:01:47 +00:00 committed by Alexandre Julliard
parent 9454801cd9
commit 67ccc0880c
6 changed files with 243 additions and 22 deletions

View file

@ -17,6 +17,46 @@
DEFAULT_DEBUG_CHANNEL(text);
static BYTE X11DRV_enum_subfont_charset_normal( UINT index )
{
return DEFAULT_CHARSET;
}
static BYTE X11DRV_enum_subfont_charset_cp932( UINT index )
{
switch ( index )
{
/* FIXME: should treat internal charset... */
case 0: return ANSI_CHARSET; /*return X11FONT_JISX0201_CHARSET;*/
/*case 1: return X11FONT_JISX0212_CHARSET;*/
}
return DEFAULT_CHARSET;
}
static BYTE X11DRV_enum_subfont_charset_cp936( UINT index )
{
FIXME( "please implement X11DRV_enum_subfont_charset_cp936!\n" );
return DEFAULT_CHARSET;
}
static BYTE X11DRV_enum_subfont_charset_cp949( UINT index )
{
switch ( index )
{
case 0: return ANSI_CHARSET;
}
return DEFAULT_CHARSET;
}
static BYTE X11DRV_enum_subfont_charset_cp950( UINT index )
{
FIXME( "please implement X11DRV_enum_subfont_charset_cp950!\n" );
return DEFAULT_CHARSET;
}
static XChar2b* X11DRV_unicode_to_char2b_sbcs( fontObject* pfo,
LPCWSTR lpwstr, UINT count )
{
@ -71,6 +111,7 @@ static XChar2b* X11DRV_unicode_to_char2b_cp932( fontObject* pfo,
XChar2b *str2b;
XChar2b *str2b_dst;
BYTE *str;
BYTE *str_src;
UINT i;
UINT codepage = pfo->fi->codepage;
char ch = pfo->fs->default_char;
@ -84,16 +125,17 @@ static XChar2b* X11DRV_unicode_to_char2b_cp932( fontObject* pfo,
}
WideCharToMultiByte( codepage, 0, lpwstr, count, str, count*2, &ch, NULL );
str_src = str;
str2b_dst = str2b;
for (i = 0; i < count; i++, str2b_dst++)
for (i = 0; i < count; i++, str_src++, str2b_dst++)
{
if ( ( str[i] >= (BYTE)0x80 && str[i] <= (BYTE)0x9f ) ||
( str[i] >= (BYTE)0xe0 && str[i] <= (BYTE)0xfc ) )
if ( ( *str_src >= (BYTE)0x80 && *str_src <= (BYTE)0x9f ) ||
( *str_src >= (BYTE)0xe0 && *str_src <= (BYTE)0xfc ) )
{
unsigned int high, low;
high = (unsigned int)str[i];
low = (unsigned int)str[i+1];
high = (unsigned int)*str_src;
low = (unsigned int)*(str_src+1);
if ( high <= 0x9f )
high = (high<<1) - 0xe0;
@ -114,12 +156,12 @@ static XChar2b* X11DRV_unicode_to_char2b_cp932( fontObject* pfo,
str2b_dst->byte1 = (unsigned char)high;
str2b_dst->byte2 = (unsigned char)low;
i++;
str_src++;
}
else
{
str2b_dst->byte1 = 0;
str2b_dst->byte2 = str[i];
str2b_dst->byte2 = *str_src;
}
}
@ -143,6 +185,7 @@ static XChar2b* X11DRV_unicode_to_char2b_cp949( fontObject* pfo,
XChar2b *str2b;
XChar2b *str2b_dst;
BYTE *str;
BYTE *str_src;
UINT i;
UINT codepage = pfo->fi->codepage;
char ch = pfo->fs->default_char;
@ -156,19 +199,20 @@ static XChar2b* X11DRV_unicode_to_char2b_cp949( fontObject* pfo,
}
WideCharToMultiByte( codepage, 0, lpwstr, count, str, count*2, &ch, NULL );
str_src = str;
str2b_dst = str2b;
for (i = 0; i < count; i++, str2b_dst++)
for (i = 0; i < count; i++, str_src++, str2b_dst++)
{
if ( str[i] & (BYTE)0x80 )
if ( (*str_src) & (BYTE)0x80 )
{
str2b_dst->byte1 = str[i];
str2b_dst->byte2 = str[i+1];
i++;
str2b_dst->byte1 = (*str_src) & 0x7f;
str2b_dst->byte2 = (*(str_src+1)) & 0x7f;
str_src++;
}
else
{
str2b_dst->byte1 = 0;
str2b_dst->byte2 = str[i];
str2b_dst->byte2 = *str_src;
}
}
@ -215,9 +259,120 @@ static void X11DRV_TextExtents_normal( fontObject* pfo, XChar2b* pstr, int count
*pwidth = info.width;
}
static
void X11DRV_DrawString_cp932( fontObject* pfo, Display* pdisp,
Drawable d, GC gc, int x, int y,
XChar2b* pstr, int count )
{
int i;
fontObject* pfo_ansi = XFONT_GetFontObject( pfo->prefobjs[0] );
for ( i = 0; i < count; i++ )
{
if ( pstr->byte1 != (BYTE)0 )
{
TSXSetFont( pdisp, gc, pfo->fs->fid );
TSXDrawString16( pdisp, d, gc, x, y, pstr, 1 );
x += TSXTextWidth16( pfo->fs, pstr, 1 );
}
else
{
if ( pfo_ansi != NULL )
{
TSXSetFont( pdisp, gc, pfo_ansi->fs->fid );
TSXDrawString16( pdisp, d, gc, x, y, pstr, 1 );
x += TSXTextWidth16( pfo_ansi->fs, pstr, 1 );
}
}
pstr ++;
}
}
static
int X11DRV_TextWidth_cp932( fontObject* pfo, XChar2b* pstr, int count )
{
int i;
int width;
fontObject* pfo_ansi = XFONT_GetFontObject( pfo->prefobjs[0] );
width = 0;
for ( i = 0; i < count; i++ )
{
if ( pstr->byte1 != (BYTE)0 )
{
width += TSXTextWidth16( pfo->fs, pstr, 1 );
}
else
{
if ( pfo_ansi != NULL )
{
width += TSXTextWidth16( pfo_ansi->fs, pstr, 1 );
}
}
pstr ++;
}
return width;
}
static
void X11DRV_DrawText_cp932( fontObject* pfo, Display* pdisp, Drawable d,
GC gc, int x, int y, XTextItem16* pitems,
int count )
{
FIXME( "ignore SBCS\n" );
TSXDrawText16( pdisp, d, gc, x, y, pitems, count );
}
static
void X11DRV_TextExtents_cp932( fontObject* pfo, XChar2b* pstr, int count,
int* pdir, int* pascent, int* pdescent,
int* pwidth )
{
XCharStruct info;
int ascent, descent, width;
int i;
fontObject* pfo_ansi = XFONT_GetFontObject( pfo->prefobjs[0] );
width = 0;
*pascent = 0;
*pdescent = 0;
for ( i = 0; i < count; i++ )
{
if ( pstr->byte1 != (BYTE)0 )
{
TSXTextExtents16( pfo->fs, pstr, 1, pdir,
&ascent, &descent, &info );
if ( *pascent < ascent ) *pascent = ascent;
if ( *pdescent < descent ) *pdescent = descent;
width += info.width;
}
else
{
if ( pfo_ansi != NULL )
{
TSXTextExtents16( pfo_ansi->fs, pstr, 1, pdir,
&ascent, &descent, &info );
if ( *pascent < ascent ) *pascent = ascent;
if ( *pdescent < descent ) *pdescent = descent;
width += info.width;
}
}
pstr ++;
}
*pwidth = width;
}
const X11DRV_CP X11DRV_cptable[X11DRV_CPTABLE_COUNT] =
{
{ /* SBCS */
X11DRV_enum_subfont_charset_normal,
X11DRV_unicode_to_char2b_sbcs,
X11DRV_DrawString_normal,
X11DRV_TextWidth_normal,
@ -225,6 +380,7 @@ const X11DRV_CP X11DRV_cptable[X11DRV_CPTABLE_COUNT] =
X11DRV_TextExtents_normal,
},
{ /* UNICODE */
X11DRV_enum_subfont_charset_normal,
X11DRV_unicode_to_char2b_unicode,
X11DRV_DrawString_normal,
X11DRV_TextWidth_normal,
@ -232,13 +388,15 @@ const X11DRV_CP X11DRV_cptable[X11DRV_CPTABLE_COUNT] =
X11DRV_TextExtents_normal,
},
{ /* CP932 */
X11DRV_enum_subfont_charset_cp932,
X11DRV_unicode_to_char2b_cp932,
X11DRV_DrawString_normal, /* FIXME */
X11DRV_TextWidth_normal, /* FIXME */
X11DRV_DrawText_normal, /* FIXME */
X11DRV_TextExtents_normal, /* FIXME */
X11DRV_DrawString_cp932,
X11DRV_TextWidth_cp932,
X11DRV_DrawText_cp932,
X11DRV_TextExtents_cp932,
},
{ /* CP936 */
X11DRV_enum_subfont_charset_cp936,
X11DRV_unicode_to_char2b_cp936,
X11DRV_DrawString_normal, /* FIXME */
X11DRV_TextWidth_normal, /* FIXME */
@ -246,6 +404,7 @@ const X11DRV_CP X11DRV_cptable[X11DRV_CPTABLE_COUNT] =
X11DRV_TextExtents_normal, /* FIXME */
},
{ /* CP949 */
X11DRV_enum_subfont_charset_cp949,
X11DRV_unicode_to_char2b_cp949,
X11DRV_DrawString_normal, /* FIXME */
X11DRV_TextWidth_normal, /* FIXME */
@ -253,6 +412,7 @@ const X11DRV_CP X11DRV_cptable[X11DRV_CPTABLE_COUNT] =
X11DRV_TextExtents_normal, /* FIXME */
},
{ /* CP950 */
X11DRV_enum_subfont_charset_cp950,
X11DRV_unicode_to_char2b_cp950,
X11DRV_DrawString_normal, /* FIXME */
X11DRV_TextWidth_normal, /* FIXME */

View file

@ -2629,8 +2629,24 @@ static fontObject* XFONT_GetCacheEntry(void)
static int XFONT_ReleaseCacheEntry(const fontObject* pfo)
{
UINT u = (UINT)(pfo - fontCache);
int i;
int ret;
if( u < fontCacheSize )
{
ret = --fontCache[u].count;
if ( ret == 0 )
{
for ( i = 0; i < X11FONT_REFOBJS_MAX; i++ )
{
if( CHECK_PFONT(pfo->prefobjs[i]) )
XFONT_ReleaseCacheEntry(__PFONT(pfo->prefobjs[i]));
}
}
return ret;
}
if( u < fontCacheSize ) return (--fontCache[u].count);
return -1;
}
@ -2785,7 +2801,8 @@ static BOOL XFONT_SetX11Trans( fontObject *pfo )
/***********************************************************************
* X Device Font Objects
*/
static X_PHYSFONT XFONT_RealizeFont( const LPLOGFONT16 plf, LPCSTR* faceMatched)
static X_PHYSFONT XFONT_RealizeFont( const LPLOGFONT16 plf,
LPCSTR* faceMatched, BOOL bSubFont )
{
UINT16 checksum;
INT index = 0;
@ -2864,8 +2881,35 @@ static X_PHYSFONT XFONT_RealizeFont( const LPLOGFONT16 plf, LPCSTR* faceMatched)
*/
pfo->lpPixmap = NULL;
for ( i = 0; i < X11FONT_REFOBJS_MAX; i++ )
pfo->prefobjs[i] = (X_PHYSFONT)0xffffffff; /* invalid value */
/* special treatment for DBCS that needs multiple fonts */
/* All member of pfo must be set correctly. */
if ( bSubFont == FALSE )
{
BYTE charset;
LOGFONT16 lfSub;
LPCSTR faceMatchedSub;
for ( i = 0; i < X11FONT_REFOBJS_MAX; i++ )
{
charset = X11DRV_cptable[pfo->fi->cptable].
penum_subfont_charset( i );
if ( charset == DEFAULT_CHARSET ) break;
lfSub = *plf;
lfSub.lfCharSet = charset;
lfSub.lfFaceName[0] = '\0'; /* FIXME? */
/* this font has sub font */
if ( i == 0 ) pfo->prefobjs[0] = (X_PHYSFONT)0;
pfo->prefobjs[i] =
XFONT_RealizeFont( &lfSub, &faceMatchedSub, TRUE );
}
}
}
if( !pfo ) /* couldn't get a new entry, get one of the cached fonts */
{
UINT current_score, score = (UINT)(-1);
@ -2982,7 +3026,7 @@ HFONT X11DRV_FONT_SelectObject( DC* dc, HFONT hfont, FONTOBJ* font )
LPCSTR faceMatched;
TRACE("hfont=%04x\n", hfont); /* to connect with the trace from RealizeFont */
physDev->font = XFONT_RealizeFont( &lf, &faceMatched );
physDev->font = XFONT_RealizeFont( &lf, &faceMatched, FALSE );
/* set face to the requested facename if it matched
* so that GetTextFace can get the correct face name

View file

@ -117,6 +117,7 @@ extern int TSXSetClipOrigin(Display*, GC, int, int);
extern int TSXSetClipRectangles(Display*, GC, int, int, XRectangle*, int, int);
extern int TSXSetDashes(Display*, GC, int, const char*, int);
extern int TSXSetFillStyle(Display*, GC, int);
extern int TSXSetFont(Display*, GC, Font);
extern int TSXSetForeground(Display*, GC, unsigned long);
extern int TSXSetFunction(Display*, GC, int);
extern int TSXSetGraphicsExposures(Display*, GC, int);

View file

@ -168,12 +168,15 @@ typedef struct {
/* Realized screen font */
typedef struct
#define X11FONT_REFOBJS_MAX 4
typedef struct
{
XFontStruct* fs; /* text metrics */
fontResource* fr; /* font family */
fontInfo* fi; /* font instance info */
Pixmap* lpPixmap; /* optional character bitmasks for synth fonts */
X_PHYSFONT prefobjs[X11FONT_REFOBJS_MAX]; /* font objects for DBCS charsets */
XFONTTRANS *lpX11Trans; /* Info for X11R6 transform */
float rescale; /* Rescale for large fonts */
@ -228,6 +231,7 @@ extern LPIFONTINFO16 XFONT_GetFontInfo( X_PHYSFONT pFont );
typedef struct tagX11DRV_CP
{
BYTE (*penum_subfont_charset)( UINT index );
XChar2b* (*punicode_to_char2b)( fontObject* pfo,
LPCWSTR lpwstr, UINT count );
void (*pDrawString)( fontObject* pfo, Display* pdisp, Drawable d, GC gc,

View file

@ -128,6 +128,7 @@ XSetClipOrigin
XSetClipRectangles
XSetDashes
XSetFillStyle
XSetFont
XSetForeground
XSetFunction
XSetGraphicsExposures

View file

@ -1146,6 +1146,17 @@ int TSXSetFillStyle(Display* a0, GC a1, int a2)
return r;
}
int TSXSetFont(Display* a0, GC a1, Font a2)
{
int r;
TRACE("Call XSetFont\n");
EnterCriticalSection( &X11DRV_CritSection );
r = XSetFont(a0, a1, a2);
LeaveCriticalSection( &X11DRV_CritSection );
TRACE("Ret XSetFont\n");
return r;
}
int TSXSetForeground(Display* a0, GC a1, unsigned long a2)
{
int r;