Commit c86cb24e authored by Hidenori Takeshima's avatar Hidenori Takeshima Committed by Alexandre Julliard

Added support for special treatments (use 2 or more fonts, codepage

conversion, etc...) for DBCS text.
parent 9b1e1dc4
......@@ -10,6 +10,7 @@ C_SRCS = \
bitmap.c \
brush.c \
clipping.c \
codepage.c \
dib.c \
graphics.c \
init.c \
......
/*
* X11 codepage handling
*
* Copyright 2000 Hidenori Takeshima <hidenori@a2.ctktv.ne.jp>
*/
#include "config.h"
#include "ts_xlib.h"
#include "windef.h"
#include "winnls.h"
#include "heap.h"
#include "x11font.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(text);
static XChar2b* X11DRV_unicode_to_char2b_sbcs( fontObject* pfo,
LPCWSTR lpwstr, UINT count )
{
XChar2b *str2b;
UINT i;
BYTE *str;
UINT codepage = pfo->fi->codepage;
char ch = pfo->fs->default_char;
if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
return NULL;
if (!(str = HeapAlloc( GetProcessHeap(), 0, count )))
{
HeapFree( GetProcessHeap(), 0, str2b );
return NULL;
}
WideCharToMultiByte( codepage, 0, lpwstr, count, str, count, &ch, NULL );
for (i = 0; i < count; i++)
{
str2b[i].byte1 = 0;
str2b[i].byte2 = str[i];
}
HeapFree( GetProcessHeap(), 0, str );
return str2b;
}
static XChar2b* X11DRV_unicode_to_char2b_unicode( fontObject* pfo,
LPCWSTR lpwstr, UINT count )
{
XChar2b *str2b;
UINT i;
if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
return NULL;
for (i = 0; i < count; i++)
{
str2b[i].byte1 = lpwstr[i] >> 8;
str2b[i].byte2 = lpwstr[i] & 0xff;
}
return str2b;
}
/* FIXME: handle jisx0212.1990... */
static XChar2b* X11DRV_unicode_to_char2b_cp932( fontObject* pfo,
LPCWSTR lpwstr, UINT count )
{
XChar2b *str2b;
XChar2b *str2b_dst;
BYTE *str;
UINT i;
UINT codepage = pfo->fi->codepage;
char ch = pfo->fs->default_char;
if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
return NULL;
if (!(str = HeapAlloc( GetProcessHeap(), 0, count*2 )))
{
HeapFree( GetProcessHeap(), 0, str2b );
return NULL;
}
WideCharToMultiByte( codepage, 0, lpwstr, count, str, count*2, &ch, NULL );
str2b_dst = str2b;
for (i = 0; i < count; i++, str2b_dst++)
{
if ( ( str[i] >= (BYTE)0x80 && str[i] <= (BYTE)0x9f ) ||
( str[i] >= (BYTE)0xe0 && str[i] <= (BYTE)0xfc ) )
{
unsigned int high, low;
high = (unsigned int)str[i];
low = (unsigned int)str[i+1];
if ( high <= 0x9f )
high = (high<<1) - 0xe0;
else
high = (high<<1) - 0x160;
if ( low < 0x9f )
{
high --;
if ( low < 0x7f )
low -= 0x1f;
else
low -= 0x20;
}
else
{
low -= 0x7e;
}
str2b_dst->byte1 = (unsigned char)high;
str2b_dst->byte2 = (unsigned char)low;
i++;
}
else
{
str2b_dst->byte1 = 0;
str2b_dst->byte2 = str[i];
}
}
HeapFree( GetProcessHeap(), 0, str );
return str2b;
}
static XChar2b* X11DRV_unicode_to_char2b_cp936( fontObject* pfo,
LPCWSTR lpwstr, UINT count )
{
FIXME( "please implement X11DRV_unicode_to_char2b_cp936!\n" );
return NULL;
}
static XChar2b* X11DRV_unicode_to_char2b_cp949( fontObject* pfo,
LPCWSTR lpwstr, UINT count )
{
XChar2b *str2b;
XChar2b *str2b_dst;
BYTE *str;
UINT i;
UINT codepage = pfo->fi->codepage;
char ch = pfo->fs->default_char;
if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
return NULL;
if (!(str = HeapAlloc( GetProcessHeap(), 0, count*2 )))
{
HeapFree( GetProcessHeap(), 0, str2b );
return NULL;
}
WideCharToMultiByte( codepage, 0, lpwstr, count, str, count*2, &ch, NULL );
str2b_dst = str2b;
for (i = 0; i < count; i++, str2b_dst++)
{
if ( str[i] & (BYTE)0x80 )
{
str2b_dst->byte1 = str[i];
str2b_dst->byte2 = str[i+1];
i++;
}
else
{
str2b_dst->byte1 = 0;
str2b_dst->byte2 = str[i];
}
}
HeapFree( GetProcessHeap(), 0, str );
return str2b;
}
static XChar2b* X11DRV_unicode_to_char2b_cp950( fontObject* pfo,
LPCWSTR lpwstr, UINT count )
{
FIXME( "please implement X11DRV_unicode_to_char2b_cp950!\n" );
return NULL;
}
static void X11DRV_DrawString_normal( fontObject* pfo, Display* pdisp,
Drawable d, GC gc, int x, int y,
XChar2b* pstr, int count )
{
TSXDrawString16( pdisp, d, gc, x, y, pstr, count );
}
static int X11DRV_TextWidth_normal( fontObject* pfo, XChar2b* pstr, int count )
{
return TSXTextWidth16( pfo->fs, pstr, count );
}
static void X11DRV_DrawText_normal( fontObject* pfo, Display* pdisp, Drawable d,
GC gc, int x, int y, XTextItem16* pitems,
int count )
{
TSXDrawText16( pdisp, d, gc, x, y, pitems, count );
}
static void X11DRV_TextExtents_normal( fontObject* pfo, XChar2b* pstr, int count,
int* pdir, int* pascent, int* pdescent,
int* pwidth )
{
XCharStruct info;
TSXTextExtents16( pfo->fs, pstr, count, pdir, pascent, pdescent, &info );
*pwidth = info.width;
}
const X11DRV_CP X11DRV_cptable[X11DRV_CPTABLE_COUNT] =
{
{ /* SBCS */
X11DRV_unicode_to_char2b_sbcs,
X11DRV_DrawString_normal,
X11DRV_TextWidth_normal,
X11DRV_DrawText_normal,
X11DRV_TextExtents_normal,
},
{ /* UNICODE */
X11DRV_unicode_to_char2b_unicode,
X11DRV_DrawString_normal,
X11DRV_TextWidth_normal,
X11DRV_DrawText_normal,
X11DRV_TextExtents_normal,
},
{ /* CP932 */
X11DRV_unicode_to_char2b_cp932,
X11DRV_DrawString_normal, /* FIXME */
X11DRV_TextWidth_normal, /* FIXME */
X11DRV_DrawText_normal, /* FIXME */
X11DRV_TextExtents_normal, /* FIXME */
},
{ /* CP936 */
X11DRV_unicode_to_char2b_cp936,
X11DRV_DrawString_normal, /* FIXME */
X11DRV_TextWidth_normal, /* FIXME */
X11DRV_DrawText_normal, /* FIXME */
X11DRV_TextExtents_normal, /* FIXME */
},
{ /* CP949 */
X11DRV_unicode_to_char2b_cp949,
X11DRV_DrawString_normal, /* FIXME */
X11DRV_TextWidth_normal, /* FIXME */
X11DRV_DrawText_normal, /* FIXME */
X11DRV_TextExtents_normal, /* FIXME */
},
{ /* CP950 */
X11DRV_unicode_to_char2b_cp950,
X11DRV_DrawString_normal, /* FIXME */
X11DRV_TextWidth_normal, /* FIXME */
X11DRV_DrawText_normal, /* FIXME */
X11DRV_TextExtents_normal, /* FIXME */
},
};
......@@ -28,74 +28,6 @@ DEFAULT_DEBUG_CHANNEL(text);
/***********************************************************************
* 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, UINT def_char )
{
XChar2b *str2b;
UINT i;
if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
return NULL;
if (codepage != 0) /* multibyte font */
{
BYTE *str;
char ch = def_char;
CPINFO cpinfo;
/* allocate the worst case count * 2 bytes */
if (!(str = HeapAlloc( GetProcessHeap(), 0, count * 2 )))
{
HeapFree( GetProcessHeap(), 0, str2b );
return NULL;
}
/* we have to convert from unicode to codepage first */
WideCharToMultiByte( codepage, 0, wstr, count, str, count, &ch, NULL );
GetCPInfo( codepage, &cpinfo );
if (cpinfo.MaxCharSize == 1)
{
for (i = 0; i < count; i++)
{
str2b[i].byte1 = 0;
str2b[i].byte2 = str[i];
}
}
else
{
XChar2b *str2b_dst = str2b;
for (i = 0; i < count; i++, str2b_dst++)
{
str2b_dst->byte2 = str[i];
if (IsDBCSLeadByteEx( codepage, str[i] ))
{
str2b_dst->byte1 = str[i + 1];
i++;
}
else
str2b_dst->byte1 = 0;
}
}
HeapFree( GetProcessHeap(), 0, str );
}
else /* codepage 0 -> unicode font */
{
for (i = 0; i < count; i++)
{
str2b[i].byte1 = wstr[i] >> 8;
str2b[i].byte2 = wstr[i] & 0xff;
}
}
return str2b;
}
/***********************************************************************
* X11DRV_ExtTextOut
*/
BOOL
......@@ -294,7 +226,7 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
}
/* Draw the text (count > 0 verified) */
if (!(str2b = unicode_to_char2b( wstr, count, pfo->fi->codepage, pfo->fs->default_char )))
if (!(str2b = X11DRV_cptable[pfo->fi->cptable].punicode_to_char2b( pfo, wstr, count )))
goto FAIL;
TSXSetForeground( display, physDev->gc, physDev->textPixel );
......@@ -302,8 +234,9 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
{
if (!dc->w.charExtra && !dc->w.breakExtra && !lpDx)
{
TSXDrawString16( display, physDev->drawable, physDev->gc,
dc->w.DCOrgX + x, dc->w.DCOrgY + y, str2b, count );
X11DRV_cptable[pfo->fi->cptable].pDrawString(
pfo, display, physDev->drawable, physDev->gc,
dc->w.DCOrgX + x, dc->w.DCOrgY + y, str2b, count );
}
else /* Now the fun begins... */
{
......@@ -336,7 +269,8 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
do
{
delta += (lpDx[i] * dc->vportExtX + extra) / dc->wndExtX
- TSXTextWidth16( font, str2b + i, 1);
- X11DRV_cptable[pfo->fi->cptable].pTextWidth(
pfo, str2b + i, 1);
pitem->nchars++;
} while ((++i < count) && !delta);
pitem++;
......@@ -363,8 +297,9 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
}
}
TSXDrawText16( display, physDev->drawable, physDev->gc,
dc->w.DCOrgX + x, dc->w.DCOrgY + y, items, pitem - items );
X11DRV_cptable[pfo->fi->cptable].pDrawText( pfo, display,
physDev->drawable, physDev->gc,
dc->w.DCOrgX + x, dc->w.DCOrgY + y, items, pitem - items );
HeapFree( GetProcessHeap(), 0, items );
}
}
......@@ -383,8 +318,9 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
int y_i = IROUND((double) (dc->w.DCOrgY + y) - offset *
pfo->lpX11Trans->b / pfo->lpX11Trans->pixelsize );
TSXDrawString16( display, physDev->drawable, physDev->gc,
x_i, y_i, &str2b[i], 1);
X11DRV_cptable[pfo->fi->cptable].pDrawString(
pfo, display, physDev->drawable, physDev->gc,
x_i, y_i, &str2b[i], 1);
if (lpDx)
offset += XLSTODS(dc, lpDx[i]);
else
......@@ -460,11 +396,12 @@ BOOL X11DRV_GetTextExtentPoint( DC *dc, LPCWSTR str, INT count,
if( pfo ) {
if( !pfo->lpX11Trans ) {
int dir, ascent, descent;
XCharStruct info;
XChar2b *p = unicode_to_char2b( str, count, pfo->fi->codepage, pfo->fs->default_char );
int info_width;
XChar2b *p = X11DRV_cptable[pfo->fi->cptable].punicode_to_char2b( pfo, str, count );
if (!p) return FALSE;
TSXTextExtents16( pfo->fs, p, count, &dir, &ascent, &descent, &info );
size->cx = abs((info.width + dc->w.breakRem + count *
X11DRV_cptable[pfo->fi->cptable].pTextExtents( pfo, p,
count, &dir, &ascent, &descent, &info_width );
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);
......
......@@ -72,12 +72,24 @@ typedef struct
#define FI_ENC_TCVN 7
#define FI_ENC_TIS620 8
enum X11DRV_CPTABLE
{
X11DRV_CPTABLE_SBCS,
X11DRV_CPTABLE_UNICODE,
X11DRV_CPTABLE_CP932,
X11DRV_CPTABLE_CP936,
X11DRV_CPTABLE_CP949,
X11DRV_CPTABLE_CP950,
X11DRV_CPTABLE_COUNT
};
typedef struct tagFontInfo
{
struct tagFontInfo* next;
UINT16 fi_flags;
UINT16 fi_encoding;
UINT16 codepage;
UINT16 cptable;
/* LFD parameters can be quite different from the actual metrics */
......@@ -96,20 +108,20 @@ typedef struct tagFontInfo
#define LFD_FIELDS 14
typedef struct
{
char* foundry;
char* family;
char* weight;
char* slant;
char* set_width;
char* add_style;
char* pixel_size;
char* point_size;
char* resolution_x;
char* resolution_y;
char* spacing;
char* average_width;
char* charset_registry;
char* charset_encoding;
const char* foundry;
const char* family;
const char* weight;
const char* slant;
const char* set_width;
const char* add_style;
const char* pixel_size;
const char* point_size;
const char* resolution_x;
const char* resolution_y;
const char* spacing;
const char* average_width;
const char* charset_registry;
const char* charset_encoding;
} LFD;
typedef struct tagFontResource
......@@ -214,4 +226,20 @@ extern fontObject* XFONT_GetFontObject( X_PHYSFONT pFont );
extern XFontStruct* XFONT_GetFontStruct( X_PHYSFONT pFont );
extern LPIFONTINFO16 XFONT_GetFontInfo( X_PHYSFONT pFont );
typedef struct tagX11DRV_CP
{
XChar2b* (*punicode_to_char2b)( fontObject* pfo,
LPCWSTR lpwstr, UINT count );
void (*pDrawString)( fontObject* pfo, Display* pdisp, Drawable d, GC gc,
int x, int y, XChar2b* pstr, int count );
int (*pTextWidth)( fontObject* pfo, XChar2b* pstr, int count );
void (*pDrawText)( fontObject* pfo, Display* pdisp, Drawable d, GC gc,
int x, int y, XTextItem16* pitems, int count );
void (*pTextExtents)( fontObject* pfo, XChar2b* pstr, int count,
int* pdir, int* pascent, int* pdescent,
int* pwidth );
} X11DRV_CP;
extern const X11DRV_CP X11DRV_cptable[X11DRV_CPTABLE_COUNT];
#endif /* __WINE_X11FONT_H */
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