Commit 2850b662 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

Assign codepage for every X11 font suffix, and use it for converting

text to display.
parent f7bf7ef7
...@@ -20,11 +20,48 @@ ...@@ -20,11 +20,48 @@
#include "x11font.h" #include "x11font.h"
#include "debugtools.h" #include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(text) DEFAULT_DEBUG_CHANNEL(text);
#define SWAP_INT(a,b) { int t = a; a = b; b = t; } #define SWAP_INT(a,b) { int t = a; a = b; b = t; }
#define IROUND(x) (int)((x)>0? (x)+0.5 : (x) - 0.5) #define IROUND(x) (int)((x)>0? (x)+0.5 : (x) - 0.5)
/***********************************************************************
* unicode_to_char2b
*
* dup a Unicode string into a XChar2b array; must be HeapFree'd by the caller
*/
static XChar2b *unicode_to_char2b( LPCWSTR wstr, UINT count, UINT codepage )
{
XChar2b *str2b;
UINT i, total_size = count * (sizeof(XChar2b) + (codepage ? sizeof(WCHAR) : 0));
if (!(str2b = HeapAlloc( GetProcessHeap(), 0, total_size ))) return NULL;
if (codepage != 0) /* a one byte font */
{
BYTE *str = (BYTE *)(str2b + count);
/* we have to convert from unicode to codepage first */
WideCharToMultiByte( codepage, 0, wstr, count, str, count, NULL, NULL );
for (i = 0; i < count; i++)
{
str2b[i].byte1 = 0;
str2b[i].byte2 = str[i];
}
}
else /* codepage 0 -> two byte font */
{
for (i = 0; i < count; i++)
{
str2b[i].byte1 = wstr[i] >> 8;
str2b[i].byte2 = wstr[i] & 0xff;
}
}
return str2b;
}
/*********************************************************************** /***********************************************************************
* X11DRV_ExtTextOut * X11DRV_ExtTextOut
*/ */
...@@ -224,12 +261,7 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags, ...@@ -224,12 +261,7 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
} }
/* Draw the text (count > 0 verified) */ /* Draw the text (count > 0 verified) */
str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) ); if (!(str2b = unicode_to_char2b( wstr, count, pfo->fi->codepage ))) goto FAIL;
if( str2b == NULL) goto FAIL;
for(i = 0; i < count; i++) {
str2b[i].byte1 = wstr[i] >> 8;
str2b[i].byte2 = wstr[i] & 0xff;
}
TSXSetForeground( display, physDev->gc, physDev->textPixel ); TSXSetForeground( display, physDev->gc, physDev->textPixel );
if(!rotated) if(!rotated)
...@@ -380,3 +412,48 @@ END: ...@@ -380,3 +412,48 @@ END:
return result; return result;
} }
/***********************************************************************
* X11DRV_GetTextExtentPoint
*/
BOOL X11DRV_GetTextExtentPoint( DC *dc, LPCWSTR str, INT count,
LPSIZE size )
{
X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
fontObject* pfo = XFONT_GetFontObject( physDev->font );
TRACE("%s %d\n", debugstr_wn(str,count), count);
if( pfo ) {
if( !pfo->lpX11Trans ) {
int dir, ascent, descent;
XCharStruct info;
XChar2b *p = unicode_to_char2b( str, count, pfo->fi->codepage );
if (!p) return FALSE;
TSXTextExtents16( pfo->fs, p, count, &dir, &ascent, &descent, &info );
size->cx = abs((info.width + dc->w.breakRem + count *
dc->w.charExtra) * dc->wndExtX / dc->vportExtX);
size->cy = abs((pfo->fs->ascent + pfo->fs->descent) *
dc->wndExtY / dc->vportExtY);
HeapFree( GetProcessHeap(), 0, p );
} else {
INT i;
float x = 0.0, y = 0.0;
for(i = 0; i < count; i++) {
x += pfo->fs->per_char ?
pfo->fs->per_char[str[i] - pfo->fs->min_char_or_byte2].attributes :
pfo->fs->min_bounds.attributes;
}
y = pfo->lpX11Trans->RAW_ASCENT + pfo->lpX11Trans->RAW_DESCENT;
TRACE("x = %f y = %f\n", x, y);
x *= pfo->lpX11Trans->pixelsize / 1000.0;
y *= pfo->lpX11Trans->pixelsize / 1000.0;
size->cx = fabs((x + dc->w.breakRem + count * dc->w.charExtra) *
dc->wndExtX / dc->vportExtX);
size->cy = fabs(y * dc->wndExtY / dc->vportExtY);
}
size->cx *= pfo->rescale;
size->cy *= pfo->rescale;
return TRUE;
}
return FALSE;
}
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "windef.h" #include "windef.h"
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "winnls.h"
#include "heap.h" #include "heap.h"
#include "options.h" #include "options.h"
#include "font.h" #include "font.h"
...@@ -104,78 +105,80 @@ typedef struct __sufch ...@@ -104,78 +105,80 @@ typedef struct __sufch
{ {
LPSTR psuffix; LPSTR psuffix;
BYTE charset; BYTE charset;
UINT16 codepage;
} SuffixCharset; } SuffixCharset;
static SuffixCharset sufch_ansi[] = { static SuffixCharset sufch_ansi[] = {
{ "0", ANSI_CHARSET }, { "0", ANSI_CHARSET, 1252 },
{ NULL, ANSI_CHARSET }}; { NULL, ANSI_CHARSET, 1252 }};
static SuffixCharset sufch_iso646[] = { static SuffixCharset sufch_iso646[] = {
{ "irv", ANSI_CHARSET }, { "irv", ANSI_CHARSET, 1252 },
{ NULL, SYMBOL_CHARSET }}; { NULL, ANSI_CHARSET, 1252 }};
static SuffixCharset sufch_iso8859[] = { static SuffixCharset sufch_iso8859[] = {
{ "1", ANSI_CHARSET }, { "1", ANSI_CHARSET, 28591 },
{ "2", EE_CHARSET }, { "2", EE_CHARSET, 28592 },
{ "3", ISO3_CHARSET }, { "3", ISO3_CHARSET, 28593 },
{ "4", ISO4_CHARSET }, { "4", ISO4_CHARSET, 28594 },
{ "5", RUSSIAN_CHARSET }, { "5", RUSSIAN_CHARSET, 28595 },
{ "6", ARABIC_CHARSET }, { "6", ARABIC_CHARSET, 28596 },
{ "7", GREEK_CHARSET }, { "7", GREEK_CHARSET, 28597 },
{ "8", HEBREW_CHARSET }, { "8", HEBREW_CHARSET, 28598 },
{ "9", TURKISH_CHARSET }, { "9", TURKISH_CHARSET, 28599 },
{ "10", BALTIC_CHARSET }, { "10", BALTIC_CHARSET, 1257 }, /* FIXME */
{ "11", THAI_CHARSET }, { "11", THAI_CHARSET, 874 }, /* FIXME */
{ "12", SYMBOL_CHARSET }, { "12", SYMBOL_CHARSET, CP_SYMBOL },
{ "13", SYMBOL_CHARSET }, { "13", SYMBOL_CHARSET, CP_SYMBOL },
{ "14", SYMBOL_CHARSET }, { "14", SYMBOL_CHARSET, CP_SYMBOL },
{ "15", ANSI_CHARSET }, { "15", ANSI_CHARSET, 1252 },
{ NULL, SYMBOL_CHARSET }}; { NULL, ANSI_CHARSET, 1252 }};
static SuffixCharset sufch_microsoft[] = { static SuffixCharset sufch_microsoft[] = {
{ "cp1250", EE_CHARSET }, { "cp1250", EE_CHARSET, 1250 },
{ "cp1251", RUSSIAN_CHARSET }, { "cp1251", RUSSIAN_CHARSET, 1251 },
{ "cp1252", ANSI_CHARSET }, { "cp1252", ANSI_CHARSET, 1252 },
{ "cp1253", GREEK_CHARSET }, { "cp1253", GREEK_CHARSET, 1253 },
{ "cp1254", TURKISH_CHARSET }, { "cp1254", TURKISH_CHARSET, 1254 },
{ "cp1255", HEBREW_CHARSET }, { "cp1255", HEBREW_CHARSET, 1255 },
{ "cp1256", ARABIC_CHARSET }, { "cp1256", ARABIC_CHARSET, 1256 },
{ "cp1257", BALTIC_CHARSET }, { "cp1257", BALTIC_CHARSET, 1257 },
{ "fontspecific", SYMBOL_CHARSET }, { "fontspecific", SYMBOL_CHARSET, CP_SYMBOL },
{ "symbol", SYMBOL_CHARSET }, { "symbol", SYMBOL_CHARSET, CP_SYMBOL },
{ NULL, SYMBOL_CHARSET }}; { NULL, ANSI_CHARSET, 1252 }};
static SuffixCharset sufch_tcvn[] = { static SuffixCharset sufch_tcvn[] = {
{ "0", TCVN_CHARSET }, { "0", TCVN_CHARSET, 1252 }, /* FIXME */
{ NULL, TCVN_CHARSET }}; { NULL, TCVN_CHARSET, 1252 }};
static SuffixCharset sufch_tis620[] = { static SuffixCharset sufch_tis620[] = {
{ "0", THAI_CHARSET }, { "0", THAI_CHARSET, 874 }, /* FIXME */
{ NULL, THAI_CHARSET }}; { NULL, THAI_CHARSET, 874 }};
static SuffixCharset sufch_viscii[] = { static SuffixCharset sufch_viscii[] = {
{ "1", VISCII_CHARSET }, { "1", VISCII_CHARSET, 1252 }, /* FIXME */
{ NULL, VISCII_CHARSET }}; { NULL, VISCII_CHARSET, 1252 }};
static SuffixCharset sufch_windows[] = { static SuffixCharset sufch_windows[] = {
{ "1250", EE_CHARSET }, { "1250", EE_CHARSET, 1250 },
{ "1251", RUSSIAN_CHARSET }, { "1251", RUSSIAN_CHARSET, 1251 },
{ "1252", ANSI_CHARSET }, { "1252", ANSI_CHARSET, 1252 },
{ "1253", GREEK_CHARSET }, { "1253", GREEK_CHARSET, 1253 },
{ "1254", TURKISH_CHARSET }, { "1254", TURKISH_CHARSET, 1254 },
{ "1255", HEBREW_CHARSET }, { "1255", HEBREW_CHARSET, 1255 },
{ "1256", ARABIC_CHARSET }, { "1256", ARABIC_CHARSET, 1256 },
{ "1257", BALTIC_CHARSET }, { "1257", BALTIC_CHARSET, 1257 },
{ NULL, BALTIC_CHARSET }}; /* CHECK/FIXME is BALTIC really the default ? */ { NULL, ANSI_CHARSET, 1252 }};
static SuffixCharset sufch_koi8[] = { static SuffixCharset sufch_koi8[] = {
{ "r", RUSSIAN_CHARSET }, { "r", RUSSIAN_CHARSET, 20866 },
{ NULL, RUSSIAN_CHARSET }}; { "u", RUSSIAN_CHARSET, 20866 },
{ NULL, RUSSIAN_CHARSET, 20866 }};
/* Each of these must be matched explicitly */ /* Each of these must be matched explicitly */
static SuffixCharset sufch_any[] = { static SuffixCharset sufch_any[] = {
{ "fontspecific", SYMBOL_CHARSET }, { "fontspecific", SYMBOL_CHARSET, CP_SYMBOL },
{ NULL, 0 }}; { NULL, 0, 0 }};
typedef struct __fet typedef struct __fet
...@@ -626,6 +629,7 @@ static int LFD_InitFontInfo( fontInfo* fi, const LFD* lfd, LPCSTR fullname ) ...@@ -626,6 +629,7 @@ static int LFD_InitFontInfo( fontInfo* fi, const LFD* lfd, LPCSTR fullname )
if( !strcasecmp(lfd->charset_encoding, boba->sufch[j].psuffix )) if( !strcasecmp(lfd->charset_encoding, boba->sufch[j].psuffix ))
{ {
fi->df.dfCharSet = boba->sufch[j].charset; fi->df.dfCharSet = boba->sufch[j].charset;
fi->codepage = boba->sufch[j].codepage;
goto done; goto done;
} }
} }
...@@ -634,6 +638,7 @@ static int LFD_InitFontInfo( fontInfo* fi, const LFD* lfd, LPCSTR fullname ) ...@@ -634,6 +638,7 @@ static int LFD_InitFontInfo( fontInfo* fi, const LFD* lfd, LPCSTR fullname )
WARN("font '%s' has unknown character encoding '%s'\n", WARN("font '%s' has unknown character encoding '%s'\n",
fullname, lfd->charset_encoding); fullname, lfd->charset_encoding);
fi->df.dfCharSet = boba->sufch[j].charset; fi->df.dfCharSet = boba->sufch[j].charset;
fi->codepage = boba->sufch[j].codepage;
j = 254; j = 254;
goto done; goto done;
} }
...@@ -643,6 +648,7 @@ static int LFD_InitFontInfo( fontInfo* fi, const LFD* lfd, LPCSTR fullname ) ...@@ -643,6 +648,7 @@ static int LFD_InitFontInfo( fontInfo* fi, const LFD* lfd, LPCSTR fullname )
for( j = 0; boba->sufch[j].psuffix; j++ ) for( j = 0; boba->sufch[j].psuffix; j++ )
; ;
fi->df.dfCharSet = boba->sufch[j].charset; fi->df.dfCharSet = boba->sufch[j].charset;
fi->codepage = boba->sufch[j].codepage;
j = 255; j = 255;
goto done; goto done;
} }
...@@ -2952,56 +2958,6 @@ BOOL X11DRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf, ...@@ -2952,56 +2958,6 @@ BOOL X11DRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf,
/*********************************************************************** /***********************************************************************
* X11DRV_GetTextExtentPoint
*/
BOOL X11DRV_GetTextExtentPoint( DC *dc, LPCWSTR str, INT count,
LPSIZE size )
{
X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
fontObject* pfo = XFONT_GetFontObject( physDev->font );
TRACE("%s %d\n", debugstr_wn(str,count), count);
if( pfo ) {
if( !pfo->lpX11Trans ) {
int dir, ascent, descent, i;
XCharStruct info;
XChar2b *p = HeapAlloc( GetProcessHeap(), 0,
count * sizeof(XChar2b) );
for(i = 0; i < count; i++) {
p[i].byte1 = str[i] >> 8;
p[i].byte2 = str[i] & 0xff;
}
TSXTextExtents16( pfo->fs, p, count, &dir, &ascent, &descent, &info );
size->cx = abs((info.width + dc->w.breakRem + count *
dc->w.charExtra) * dc->wndExtX / dc->vportExtX);
size->cy = abs((pfo->fs->ascent + pfo->fs->descent) *
dc->wndExtY / dc->vportExtY);
HeapFree( GetProcessHeap(), 0, p );
} else {
INT i;
float x = 0.0, y = 0.0;
for(i = 0; i < count; i++) {
x += pfo->fs->per_char ?
pfo->fs->per_char[str[i] - pfo->fs->min_char_or_byte2].attributes :
pfo->fs->min_bounds.attributes;
}
y = pfo->lpX11Trans->RAW_ASCENT + pfo->lpX11Trans->RAW_DESCENT;
TRACE("x = %f y = %f\n", x, y);
x *= pfo->lpX11Trans->pixelsize / 1000.0;
y *= pfo->lpX11Trans->pixelsize / 1000.0;
size->cx = fabs((x + dc->w.breakRem + count * dc->w.charExtra) *
dc->wndExtX / dc->vportExtX);
size->cy = fabs(y * dc->wndExtY / dc->vportExtY);
}
size->cx *= pfo->rescale;
size->cy *= pfo->rescale;
return TRUE;
}
return FALSE;
}
/***********************************************************************
* X11DRV_GetTextMetrics * X11DRV_GetTextMetrics
*/ */
BOOL X11DRV_GetTextMetrics(DC *dc, TEXTMETRICA *metrics) BOOL X11DRV_GetTextMetrics(DC *dc, TEXTMETRICA *metrics)
......
...@@ -77,6 +77,7 @@ typedef struct tagFontInfo ...@@ -77,6 +77,7 @@ typedef struct tagFontInfo
struct tagFontInfo* next; struct tagFontInfo* next;
UINT16 fi_flags; UINT16 fi_flags;
UINT16 fi_encoding; UINT16 fi_encoding;
UINT16 codepage;
/* LFD parameters can be quite different from the actual metrics */ /* LFD parameters can be quite different from the actual metrics */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment