Authors: Ove Kaaven <ovek@transgaming.com>, Andrew Lewycky <andrew@transgaming.com...
[wine/multimedia.git] / graphics / x11drv / codepage.c
blobcfcbd95f95ef92c20549ea39ead0558620c6046a
1 /*
2 * X11 codepage handling
4 * Copyright 2000 Hidenori Takeshima <hidenori@a2.ctktv.ne.jp>
5 */
7 #include "config.h"
9 #include "ts_xlib.h"
11 #include <math.h>
13 #include "windef.h"
14 #include "winnls.h"
15 #include "heap.h"
16 #include "x11font.h"
17 #include "debugtools.h"
19 DEFAULT_DEBUG_CHANNEL(text);
21 /***********************************************************************
22 * IsLegalDBCSChar for cp932/936/949/950/euc
24 static inline
25 int IsLegalDBCSChar_cp932( BYTE lead, BYTE trail )
27 return ( ( ( lead >= (BYTE)0x81 && lead <= (BYTE)0x9f ) ||
28 ( lead >= (BYTE)0xe0 && lead <= (BYTE)0xfc ) ) &&
29 ( ( trail >= (BYTE)0x40 && trail <= (BYTE)0x7e ) ||
30 ( trail >= (BYTE)0x80 && trail <= (BYTE)0xfc ) ) );
33 static inline
34 int IsLegalDBCSChar_cp936( BYTE lead, BYTE trail )
36 return ( ( lead >= (BYTE)0x81 && lead <= (BYTE)0xfe ) &&
37 ( trail >= (BYTE)0x40 && trail <= (BYTE)0xfe ) );
40 static inline
41 int IsLegalDBCSChar_cp949( BYTE lead, BYTE trail )
43 return ( ( lead >= (BYTE)0x81 && lead <= (BYTE)0xfe ) &&
44 ( trail >= (BYTE)0x41 && trail <= (BYTE)0xfe ) );
47 static inline
48 int IsLegalDBCSChar_cp950( BYTE lead, BYTE trail )
50 return ( ( lead >= (BYTE)0x81 && lead <= (BYTE)0xfe ) &&
51 ( ( trail >= (BYTE)0x40 && trail <= (BYTE)0x7e ) ||
52 ( trail >= (BYTE)0xa1 && trail <= (BYTE)0xfe ) ) );
55 static inline
56 int IsLegalDBCSChar_euc( BYTE lead, BYTE trail )
58 return ( ( lead >= (BYTE)0xa1 && lead <= (BYTE)0xfe ) &&
59 ( trail >= (BYTE)0xa1 && trail <= (BYTE)0xfe ) );
63 /***********************************************************************
64 * DBCSCharToXChar2b for cp932/euc
67 static inline
68 void DBCSCharToXChar2b_cp932( XChar2b* pch, BYTE lead, BYTE trail )
70 unsigned int high, low;
72 high = (unsigned int)lead;
73 low = (unsigned int)trail;
75 if ( high <= 0x9f )
76 high = (high<<1) - 0xe0;
77 else
78 high = (high<<1) - 0x160;
79 if ( low < 0x9f )
81 high --;
82 if ( low < 0x7f )
83 low -= 0x1f;
84 else
85 low -= 0x20;
87 else
89 low -= 0x7e;
92 pch->byte1 = (unsigned char)high;
93 pch->byte2 = (unsigned char)low;
96 static inline
97 void DBCSCharToXChar2b_euc( XChar2b* pch, BYTE lead, BYTE trail )
99 pch->byte1 = lead & (BYTE)0x7f;
100 pch->byte2 = trail & (BYTE)0x7f;
106 static WORD X11DRV_enum_subfont_charset_normal( UINT index )
108 return DEFAULT_CHARSET;
111 static WORD X11DRV_enum_subfont_charset_cp932( UINT index )
113 switch ( index )
115 case 0: return X11FONT_JISX0201_CHARSET;
116 case 1: return X11FONT_JISX0212_CHARSET;
119 return DEFAULT_CHARSET;
122 static WORD X11DRV_enum_subfont_charset_cp936( UINT index )
124 switch ( index )
126 case 0: return ANSI_CHARSET;
129 return DEFAULT_CHARSET;
132 static WORD X11DRV_enum_subfont_charset_cp949( UINT index )
134 switch ( index )
136 case 0: return ANSI_CHARSET;
139 return DEFAULT_CHARSET;
142 static WORD X11DRV_enum_subfont_charset_cp950( UINT index )
144 FIXME( "please implement X11DRV_enum_subfont_charset_cp950!\n" );
145 return DEFAULT_CHARSET;
149 static XChar2b* X11DRV_unicode_to_char2b_sbcs( fontObject* pfo,
150 LPCWSTR lpwstr, UINT count )
152 XChar2b *str2b;
153 UINT i;
154 BYTE *str;
155 UINT codepage = pfo->fi->codepage;
156 char ch = pfo->fs->default_char;
158 if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
159 return NULL;
160 if (!(str = HeapAlloc( GetProcessHeap(), 0, count )))
162 HeapFree( GetProcessHeap(), 0, str2b );
163 return NULL;
166 WideCharToMultiByte( codepage, 0, lpwstr, count, str, count, &ch, NULL );
168 for (i = 0; i < count; i++)
170 str2b[i].byte1 = 0;
171 str2b[i].byte2 = str[i];
173 HeapFree( GetProcessHeap(), 0, str );
175 return str2b;
178 static XChar2b* X11DRV_unicode_to_char2b_unicode( fontObject* pfo,
179 LPCWSTR lpwstr, UINT count )
181 XChar2b *str2b;
182 UINT i;
184 if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
185 return NULL;
187 for (i = 0; i < count; i++)
189 str2b[i].byte1 = lpwstr[i] >> 8;
190 str2b[i].byte2 = lpwstr[i] & 0xff;
193 return str2b;
196 /* FIXME: handle jisx0212.1990... */
197 static XChar2b* X11DRV_unicode_to_char2b_cp932( fontObject* pfo,
198 LPCWSTR lpwstr, UINT count )
200 XChar2b *str2b;
201 XChar2b *str2b_dst;
202 BYTE *str;
203 BYTE *str_src;
204 UINT i;
205 char ch = pfo->fs->default_char;
207 if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
208 return NULL;
209 if (!(str = HeapAlloc( GetProcessHeap(), 0, count*2 )))
211 HeapFree( GetProcessHeap(), 0, str2b );
212 return NULL;
215 /* handle jisx0212.1990... */
216 WideCharToMultiByte( 932, 0, lpwstr, count, str, count*2, &ch, NULL );
218 str_src = str;
219 str2b_dst = str2b;
220 for (i = 0; i < count; i++, str_src++, str2b_dst++)
222 if ( IsLegalDBCSChar_cp932( *str_src, *(str_src+1) ) )
224 DBCSCharToXChar2b_cp932( str2b_dst, *str_src, *(str_src+1) );
225 str_src++;
227 else
229 str2b_dst->byte1 = 0;
230 str2b_dst->byte2 = *str_src;
234 HeapFree( GetProcessHeap(), 0, str );
236 return str2b;
240 static XChar2b* X11DRV_unicode_to_char2b_cp936( fontObject* pfo,
241 LPCWSTR lpwstr, UINT count )
243 XChar2b *str2b;
244 XChar2b *str2b_dst;
245 BYTE *str;
246 BYTE *str_src;
247 UINT i;
248 char ch = pfo->fs->default_char;
250 if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
251 return NULL;
252 if (!(str = HeapAlloc( GetProcessHeap(), 0, count*2 )))
254 HeapFree( GetProcessHeap(), 0, str2b );
255 return NULL;
257 WideCharToMultiByte( 936, 0, lpwstr, count, str, count*2, &ch, NULL );
259 str_src = str;
260 str2b_dst = str2b;
261 for (i = 0; i < count; i++, str_src++, str2b_dst++)
263 if ( IsLegalDBCSChar_cp936( *str_src, *(str_src+1) ) )
265 if ( IsLegalDBCSChar_euc( *str_src, *(str_src+1) ) )
267 DBCSCharToXChar2b_euc( str2b_dst, *str_src, *(str_src+1) );
269 else
271 /* FIXME */
272 str2b_dst->byte1 = 0;
273 str2b_dst->byte2 = 0;
275 str_src++;
277 else
279 str2b_dst->byte1 = 0;
280 str2b_dst->byte2 = *str_src;
284 HeapFree( GetProcessHeap(), 0, str );
286 return str2b;
289 static XChar2b* X11DRV_unicode_to_char2b_cp949( fontObject* pfo,
290 LPCWSTR lpwstr, UINT count )
292 XChar2b *str2b;
293 XChar2b *str2b_dst;
294 BYTE *str;
295 BYTE *str_src;
296 UINT i;
297 char ch = pfo->fs->default_char;
299 if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
300 return NULL;
301 if (!(str = HeapAlloc( GetProcessHeap(), 0, count*2 )))
303 HeapFree( GetProcessHeap(), 0, str2b );
304 return NULL;
306 WideCharToMultiByte( 949, 0, lpwstr, count, str, count*2, &ch, NULL );
308 str_src = str;
309 str2b_dst = str2b;
310 for (i = 0; i < count; i++, str_src++, str2b_dst++)
312 if ( IsLegalDBCSChar_cp949( *str_src, *(str_src+1) ) )
314 if ( IsLegalDBCSChar_euc( *str_src, *(str_src+1) ) )
316 DBCSCharToXChar2b_euc( str2b_dst, *str_src, *(str_src+1) );
318 else
320 /* FIXME */
321 str2b_dst->byte1 = 0;
322 str2b_dst->byte2 = 0;
324 str_src++;
326 else
328 str2b_dst->byte1 = 0;
329 str2b_dst->byte2 = *str_src;
333 HeapFree( GetProcessHeap(), 0, str );
335 return str2b;
339 static XChar2b* X11DRV_unicode_to_char2b_cp950( fontObject* pfo,
340 LPCWSTR lpwstr, UINT count )
342 FIXME( "please implement X11DRV_unicode_to_char2b_cp950!\n" );
343 return NULL;
347 static void X11DRV_DrawString_normal( fontObject* pfo, Display* pdisp,
348 Drawable d, GC gc, int x, int y,
349 XChar2b* pstr, int count )
351 TSXDrawString16( pdisp, d, gc, x, y, pstr, count );
354 static int X11DRV_TextWidth_normal( fontObject* pfo, XChar2b* pstr, int count )
356 return TSXTextWidth16( pfo->fs, pstr, count );
359 static void X11DRV_DrawText_normal( fontObject* pfo, Display* pdisp, Drawable d,
360 GC gc, int x, int y, XTextItem16* pitems,
361 int count )
363 TSXDrawText16( pdisp, d, gc, x, y, pitems, count );
366 static void X11DRV_TextExtents_normal( fontObject* pfo, XChar2b* pstr, int count,
367 int* pdir, int* pascent, int* pdescent,
368 int* pwidth )
370 XCharStruct info;
372 TSXTextExtents16( pfo->fs, pstr, count, pdir, pascent, pdescent, &info );
373 *pwidth = info.width;
376 static void X11DRV_GetTextMetricsA_normal( fontObject* pfo, LPTEXTMETRICA pTM )
378 LPIFONTINFO16 pdf = &pfo->fi->df;
380 if( ! pfo->lpX11Trans ) {
381 pTM->tmAscent = pfo->fs->ascent;
382 pTM->tmDescent = pfo->fs->descent;
383 } else {
384 pTM->tmAscent = pfo->lpX11Trans->ascent;
385 pTM->tmDescent = pfo->lpX11Trans->descent;
388 pTM->tmAscent *= pfo->rescale;
389 pTM->tmDescent *= pfo->rescale;
391 pTM->tmHeight = pTM->tmAscent + pTM->tmDescent;
393 pTM->tmAveCharWidth = pfo->foAvgCharWidth * pfo->rescale;
394 pTM->tmMaxCharWidth = pfo->foMaxCharWidth * pfo->rescale;
396 pTM->tmInternalLeading = pfo->foInternalLeading * pfo->rescale;
397 pTM->tmExternalLeading = pdf->dfExternalLeading * pfo->rescale;
399 pTM->tmStruckOut = (pfo->fo_flags & FO_SYNTH_STRIKEOUT )
400 ? 1 : pdf->dfStrikeOut;
401 pTM->tmUnderlined = (pfo->fo_flags & FO_SYNTH_UNDERLINE )
402 ? 1 : pdf->dfUnderline;
404 pTM->tmOverhang = 0;
405 if( pfo->fo_flags & FO_SYNTH_ITALIC )
407 pTM->tmOverhang += pTM->tmHeight/3;
408 pTM->tmItalic = 1;
409 } else
410 pTM->tmItalic = pdf->dfItalic;
412 pTM->tmWeight = pdf->dfWeight;
413 if( pfo->fo_flags & FO_SYNTH_BOLD )
415 pTM->tmOverhang++;
416 pTM->tmWeight += 100;
419 pTM->tmFirstChar = pdf->dfFirstChar;
420 pTM->tmLastChar = pdf->dfLastChar;
421 pTM->tmDefaultChar = pdf->dfDefaultChar;
422 pTM->tmBreakChar = pdf->dfBreakChar;
424 pTM->tmCharSet = pdf->dfCharSet;
425 pTM->tmPitchAndFamily = pdf->dfPitchAndFamily;
427 pTM->tmDigitizedAspectX = pdf->dfHorizRes;
428 pTM->tmDigitizedAspectY = pdf->dfVertRes;
433 static
434 void X11DRV_DrawString_dbcs( fontObject* pfo, Display* pdisp,
435 Drawable d, GC gc, int x, int y,
436 XChar2b* pstr, int count )
438 XTextItem16 item;
440 item.chars = pstr;
441 item.delta = 0;
442 item.nchars = count;
443 item.font = None;
444 X11DRV_cptable[pfo->fi->cptable].pDrawText(
445 pfo, pdisp, d, gc, x, y, &item, 1 );
448 static
449 int X11DRV_TextWidth_dbcs_2fonts( fontObject* pfo, XChar2b* pstr, int count )
451 int i;
452 int width;
453 int curfont;
454 fontObject* pfos[X11FONT_REFOBJS_MAX+1];
456 pfos[0] = XFONT_GetFontObject( pfo->prefobjs[0] );
457 pfos[1] = pfo;
458 if ( pfos[0] == NULL ) pfos[0] = pfo;
460 width = 0;
461 for ( i = 0; i < count; i++ )
463 curfont = ( pstr->byte1 != 0 ) ? 1 : 0;
464 width += TSXTextWidth16( pfos[curfont]->fs, pstr, 1 );
465 pstr ++;
468 return width;
471 static
472 void X11DRV_DrawText_dbcs_2fonts( fontObject* pfo, Display* pdisp, Drawable d,
473 GC gc, int x, int y, XTextItem16* pitems,
474 int count )
476 int i, nitems, prevfont = -1, curfont;
477 XChar2b* pstr;
478 XTextItem16* ptibuf;
479 XTextItem16* pti;
480 fontObject* pfos[X11FONT_REFOBJS_MAX+1];
482 pfos[0] = XFONT_GetFontObject( pfo->prefobjs[0] );
483 pfos[1] = pfo;
484 if ( pfos[0] == NULL ) pfos[0] = pfo;
486 nitems = 0;
487 for ( i = 0; i < count; i++ )
488 nitems += pitems->nchars;
489 ptibuf = HeapAlloc( GetProcessHeap(), 0, sizeof(XTextItem16) * nitems );
490 if ( ptibuf == NULL )
491 return; /* out of memory */
493 pti = ptibuf;
494 while ( count-- > 0 )
496 pti->chars = pstr = pitems->chars;
497 pti->delta = pitems->delta;
498 pti->font = None;
499 for ( i = 0; i < pitems->nchars; i++, pstr++ )
501 curfont = ( pstr->byte1 != 0 ) ? 1 : 0;
502 if ( curfont != prevfont )
504 if ( pstr != pti->chars )
506 pti->nchars = pstr - pti->chars;
507 pti ++;
508 pti->chars = pstr;
509 pti->delta = 0;
511 pti->font = pfos[curfont]->fs->fid;
512 prevfont = curfont;
515 pti->nchars = pstr - pti->chars;
516 pitems ++; pti ++;
518 TSXDrawText16( pdisp, d, gc, x, y, ptibuf, pti - ptibuf );
519 HeapFree( GetProcessHeap(), 0, ptibuf );
522 static
523 void X11DRV_TextExtents_dbcs_2fonts( fontObject* pfo, XChar2b* pstr, int count,
524 int* pdir, int* pascent, int* pdescent,
525 int* pwidth )
527 XCharStruct info;
528 int ascent, descent, width;
529 int i;
530 int curfont;
531 fontObject* pfos[X11FONT_REFOBJS_MAX+1];
533 pfos[0] = XFONT_GetFontObject( pfo->prefobjs[0] );
534 pfos[1] = pfo;
535 if ( pfos[0] == NULL ) pfos[0] = pfo;
537 width = 0;
538 *pascent = 0;
539 *pdescent = 0;
540 for ( i = 0; i < count; i++ )
542 curfont = ( pstr->byte1 != 0 ) ? 1 : 0;
543 TSXTextExtents16( pfos[curfont]->fs, pstr, 1, pdir,
544 &ascent, &descent, &info );
545 if ( *pascent < ascent ) *pascent = ascent;
546 if ( *pdescent < descent ) *pdescent = descent;
547 width += info.width;
549 pstr ++;
552 *pwidth = width;
555 static void X11DRV_GetTextMetricsA_cp932( fontObject* pfo, LPTEXTMETRICA pTM )
557 fontObject* pfo_ansi = XFONT_GetFontObject( pfo->prefobjs[0] );
558 LPIFONTINFO16 pdf = &pfo->fi->df;
559 LPIFONTINFO16 pdf_ansi;
561 pdf_ansi = ( pfo_ansi != NULL ) ? (&pfo_ansi->fi->df) : pdf;
563 if( ! pfo->lpX11Trans ) {
564 pTM->tmAscent = pfo->fs->ascent;
565 pTM->tmDescent = pfo->fs->descent;
566 } else {
567 pTM->tmAscent = pfo->lpX11Trans->ascent;
568 pTM->tmDescent = pfo->lpX11Trans->descent;
571 pTM->tmAscent *= pfo->rescale;
572 pTM->tmDescent *= pfo->rescale;
574 pTM->tmHeight = pTM->tmAscent + pTM->tmDescent;
576 if ( pfo_ansi != NULL )
578 pTM->tmAveCharWidth = floor((pfo_ansi->foAvgCharWidth * 2.0 + pfo->foAvgCharWidth) / 3.0 * pfo->rescale + 0.5);
579 pTM->tmMaxCharWidth = __max(pfo_ansi->foMaxCharWidth, pfo->foMaxCharWidth) * pfo->rescale;
581 else
583 pTM->tmAveCharWidth = floor((pfo->foAvgCharWidth * pfo->rescale + 1.0) / 2.0);
584 pTM->tmMaxCharWidth = pfo->foMaxCharWidth * pfo->rescale;
587 pTM->tmInternalLeading = pfo->foInternalLeading * pfo->rescale;
588 pTM->tmExternalLeading = pdf->dfExternalLeading * pfo->rescale;
590 pTM->tmStruckOut = (pfo->fo_flags & FO_SYNTH_STRIKEOUT )
591 ? 1 : pdf->dfStrikeOut;
592 pTM->tmUnderlined = (pfo->fo_flags & FO_SYNTH_UNDERLINE )
593 ? 1 : pdf->dfUnderline;
595 pTM->tmOverhang = 0;
596 if( pfo->fo_flags & FO_SYNTH_ITALIC )
598 pTM->tmOverhang += pTM->tmHeight/3;
599 pTM->tmItalic = 1;
600 } else
601 pTM->tmItalic = pdf->dfItalic;
603 pTM->tmWeight = pdf->dfWeight;
604 if( pfo->fo_flags & FO_SYNTH_BOLD )
606 pTM->tmOverhang++;
607 pTM->tmWeight += 100;
610 pTM->tmFirstChar = pdf_ansi->dfFirstChar;
611 pTM->tmLastChar = pdf_ansi->dfLastChar;
612 pTM->tmDefaultChar = pdf_ansi->dfDefaultChar;
613 pTM->tmBreakChar = pdf_ansi->dfBreakChar;
615 pTM->tmCharSet = pdf->dfCharSet;
616 pTM->tmPitchAndFamily = pdf->dfPitchAndFamily;
618 pTM->tmDigitizedAspectX = pdf->dfHorizRes;
619 pTM->tmDigitizedAspectY = pdf->dfVertRes;
626 const X11DRV_CP X11DRV_cptable[X11DRV_CPTABLE_COUNT] =
628 { /* SBCS */
629 X11DRV_enum_subfont_charset_normal,
630 X11DRV_unicode_to_char2b_sbcs,
631 X11DRV_DrawString_normal,
632 X11DRV_TextWidth_normal,
633 X11DRV_DrawText_normal,
634 X11DRV_TextExtents_normal,
635 X11DRV_GetTextMetricsA_normal,
637 { /* UNICODE */
638 X11DRV_enum_subfont_charset_normal,
639 X11DRV_unicode_to_char2b_unicode,
640 X11DRV_DrawString_normal,
641 X11DRV_TextWidth_normal,
642 X11DRV_DrawText_normal,
643 X11DRV_TextExtents_normal,
644 X11DRV_GetTextMetricsA_normal,
646 { /* CP932 */
647 X11DRV_enum_subfont_charset_cp932,
648 X11DRV_unicode_to_char2b_cp932,
649 X11DRV_DrawString_dbcs,
650 X11DRV_TextWidth_dbcs_2fonts,
651 X11DRV_DrawText_dbcs_2fonts,
652 X11DRV_TextExtents_dbcs_2fonts,
653 X11DRV_GetTextMetricsA_cp932,
655 { /* CP936 */
656 X11DRV_enum_subfont_charset_cp936,
657 X11DRV_unicode_to_char2b_cp936,
658 X11DRV_DrawString_dbcs,
659 X11DRV_TextWidth_dbcs_2fonts,
660 X11DRV_DrawText_dbcs_2fonts,
661 X11DRV_TextExtents_dbcs_2fonts,
662 X11DRV_GetTextMetricsA_normal, /* FIXME */
664 { /* CP949 */
665 X11DRV_enum_subfont_charset_cp949,
666 X11DRV_unicode_to_char2b_cp949,
667 X11DRV_DrawString_dbcs,
668 X11DRV_TextWidth_dbcs_2fonts,
669 X11DRV_DrawText_dbcs_2fonts,
670 X11DRV_TextExtents_dbcs_2fonts,
671 X11DRV_GetTextMetricsA_normal, /* FIXME */
673 { /* CP950 */
674 X11DRV_enum_subfont_charset_cp950,
675 X11DRV_unicode_to_char2b_cp950,
676 X11DRV_DrawString_normal, /* FIXME */
677 X11DRV_TextWidth_normal, /* FIXME */
678 X11DRV_DrawText_normal, /* FIXME */
679 X11DRV_TextExtents_normal, /* FIXME */
680 X11DRV_GetTextMetricsA_normal, /* FIXME */